active_record_bulk_insert 1.0.1 → 1.0.2

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: 98abb1e9088469a72b2a1fdad538efbad45f0ff3
4
- data.tar.gz: 6af5ead385884af2ba352c78066903402f7ace59
3
+ metadata.gz: c3d14d962a4b75438e6782bcfb7ae0d25c9f1bd5
4
+ data.tar.gz: f8878c7b4b47eb1f5daaff16135ceb03b491830b
5
5
  SHA512:
6
- metadata.gz: b880829f30a4908a6f9409d74059ee0afaaea2fdde49dfd988df0fc84490a5a9b0d74828e6195717c868694f084462646531cb2ad76be91a4d35f553743a30e8
7
- data.tar.gz: 792930311de34e535b98534c4b7158b5826028e431010c0c2728ffa0ad63da04bec8b1761e07ff87df8ae3d741e5071b789bf1463b43e322ad1bbd1027972088
6
+ metadata.gz: 5a0fdf6b3acad9e058d3bea8c2cc304edd6fab80d278a7ade049debd93cade9283138cd00a91cb05429c25de179cb4825c5e20915c14f2bab3796238fa732a84
7
+ data.tar.gz: 417f5e0f23e63e5d7ee3e51af9aaa25c942a95185b30ef57869e663a32a49b90deb270f2b2379e076511e80b3ac919cedde31219de610e3ed9b8df30cffdd8f3
data/README.md CHANGED
@@ -6,6 +6,15 @@
6
6
 
7
7
  ### Quick Example
8
8
 
9
+ For -v 1.0.0
10
+
11
+ ```ruby
12
+ #Gemfile
13
+ gem "active_record_bulk_insert", :require => 'base'
14
+ ```
15
+
16
+ For subsequent versions
17
+
9
18
  ```ruby
10
19
  #Gemfile
11
20
  gem "active_record_bulk_insert"
@@ -50,6 +59,14 @@ User.bulk_insert(users, :use_provided_primary_key => true)
50
59
  ```
51
60
  *note this is only available from ActiveRecord 4.0 as id was protected from mass-assignment in ActiveRecord < 4.0*
52
61
 
62
+ ### Disable default timestamps
63
+
64
+ *From version 1.0.2 updated_at and created_at are provided by default*
65
+
66
+ ```ruby
67
+ User.bulk_insert(users, :disable_timestamps => true)
68
+ ```
69
+
53
70
  ### Bulk insert in batches
54
71
 
55
72
  ```ruby
@@ -8,15 +8,17 @@ ActiveRecord::Base.class_eval do
8
8
  end
9
9
 
10
10
  def self.bulk_insert(attrs, options = {})
11
+ return [] if attrs.empty?
12
+
11
13
  use_provided_primary_key = options.fetch(:use_provided_primary_key, false)
12
- attributes = _resolve_record(attrs.first, use_provided_primary_key).keys.join(", ")
14
+ attributes = _resolve_record(attrs.first, options).keys.join(", ")
13
15
 
14
16
  if options.fetch(:validate, false)
15
17
  attrs, invalid = attrs.partition { |record| _validate(record) }
16
18
  end
17
19
 
18
20
  values_sql = attrs.map do |record|
19
- "(#{_resolve_record(record, use_provided_primary_key).values.map { |r| sanitize(r) }.join(', ')})"
21
+ "(#{_resolve_record(record, options).values.map { |r| sanitize(r) }.join(', ')})"
20
22
  end.join(",")
21
23
 
22
24
  sql = <<-SQL
@@ -29,16 +31,12 @@ ActiveRecord::Base.class_eval do
29
31
  invalid
30
32
  end
31
33
 
32
- def self._resolve_record(record, use_provided_primary_key)
33
- if record.is_a?(Hash) && use_provided_primary_key
34
- record.except(primary_key).except(primary_key.to_sym)
35
- elsif record.is_a?(Hash)
36
- record
37
- elsif record.is_a?(ActiveRecord::Base) && use_provided_primary_key
38
- record.attributes
39
- elsif record.is_a?(ActiveRecord::Base)
40
- record.attributes.except(primary_key).except(primary_key.to_sym)
41
- end
34
+ def self._resolve_record(record, options)
35
+ time = ActiveRecord::Base.default_timezone == :utc ? Time.now.utc : Time.now
36
+ _record = record.is_a?(ActiveRecord::Base) ? record.attributes : record
37
+ _record.merge!("created_at" => time, "updated_at" => time) unless options.fetch(:disable_timestamps, false)
38
+ _record = _record.except(primary_key).except(primary_key.to_sym) unless options.fetch(:use_provided_primary_key, false)
39
+ _record
42
40
  end
43
41
 
44
42
  def self._validate(record)
@@ -1,89 +1,115 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe SampleRecord do
4
- describe "bulk_insert" do
5
- it "inserts records into the DB" do
6
- ActiveRecord::ConnectionAdapters::SQLite3Adapter.any_instance.should_receive(:execute).with do |params|
7
- params.should include("INSERT INTO \"sample_records\"")
8
- params.should include("Foo")
9
- params.should include("30")
10
- end.once
11
- SampleRecord.bulk_insert([{:name => "Foo", :age => 30}])
12
- end
13
-
14
- it "inserts records into the DB and increases count of records" do
15
- records = 5.times.map { |i| SampleRecord.new(:age => i + (30..50).to_a.sample, :name => "Foo#{i}").attributes }
16
- expect {SampleRecord.bulk_insert(records)}.to change{SampleRecord.count}.by(records.size)
17
- end
18
-
19
- it "inserts multiple records into the DB in a single insert statement" do
20
- records = 10.times.map { |i| {:age => 4, :name => "Foo#{i}"} }
21
-
22
- ActiveRecord::ConnectionAdapters::SQLite3Adapter.any_instance.should_receive(:execute).with do |params|
23
- matchdata = params.match(/insert into "sample_records"/i)
24
- matchdata.to_a.count.should == 1
25
- records.each do |record|
26
- params.should include(record[:age].to_s)
27
- params.should include(record[:name])
28
- end
29
- end.once
30
-
31
- SampleRecord.bulk_insert(records)
32
- end
33
-
34
- it "relies on the DB to provide primary_key if :use_provided_primary_key is false or nil" do
35
- records = 10.times.map { |i| SampleRecord.new(:id => 10000 + i, :age => 4, :name => "Foo#{i}") }
36
-
37
- ActiveRecord::ConnectionAdapters::SQLite3Adapter.any_instance.should_receive(:execute).with do |params|
38
- records.each do |record|
39
- params.should_not include(record.id.to_s)
40
- end
41
- end
42
-
43
- SampleRecord.bulk_insert(records)
44
- end
45
-
46
- it "uses provided primary_key if :use_provided_primary_key is true" do
47
- records = 10.times.map { |i| SampleRecord.new(:id => 10000 + i, :age => 4, :name => "Foo#{i}") }
48
-
49
- SampleRecord.bulk_insert(records, :use_provided_primary_key => true)
50
- records.each do |record|
51
- SampleRecord.exists?(:id => record.id).should be_true
52
- end
53
- end
54
-
55
- it "support insertion of ActiveRecord objects" do
56
- records = 10.times.map { |i| SampleRecord.new(:age => 4, :name => "Foo#{i}") }
57
-
58
- ActiveRecord::ConnectionAdapters::SQLite3Adapter.any_instance.should_receive(:execute).with do |params|
59
- matchdata = params.match(/insert into "sample_records"/i)
60
- matchdata.to_a.count.should == 1
61
- records.each do |record|
62
- params.should include(record.age.to_s)
63
- params.should include(record.name)
64
- end
65
- end.once
66
-
67
- SampleRecord.bulk_insert(records)
68
- end
69
-
70
- context "validations" do
71
- it "should not persist invalid records if ':validate => true' is specified" do
72
- SampleRecord.send(:validates, :name, :presence => true)
73
- expect {SampleRecord.bulk_insert([:age => 30], :validate => true)}.to_not change{SampleRecord.count}
74
- end
75
- end
76
- end
77
-
78
- describe "bulk_insert_in_batches" do
79
- it "allows you to specify a batch_size" do
80
- records = 10.times.map { |i| SampleRecord.new(:age => 4, :name => "Foo#{i}").attributes }
81
-
82
- ActiveRecord::ConnectionAdapters::SQLite3Adapter.any_instance.should_receive(:execute).with do |params|
83
- params.should include("INSERT INTO \"sample_records\"")
84
- end.exactly(5).times
85
-
86
- SampleRecord.bulk_insert_in_batches(records, :batch_size => 2)
87
- end
88
- end
4
+ describe "bulk_insert" do
5
+ it "inserts records into the DB" do
6
+ ActiveRecord::ConnectionAdapters::SQLite3Adapter.any_instance.should_receive(:execute).with do |params|
7
+ params.should include("INSERT INTO \"sample_records\"")
8
+ params.should include("Foo")
9
+ params.should include("30")
10
+ end.once
11
+ SampleRecord.bulk_insert([{:name => "Foo", :age => 30}])
12
+ end
13
+
14
+ it "inserts records into the DB and increases count of records" do
15
+ records = 5.times.map { |i| SampleRecord.new(:age => i + (30..50).to_a.sample, :name => "Foo#{i}").attributes }
16
+ expect {SampleRecord.bulk_insert(records)}.to change{SampleRecord.count}.by(records.size)
17
+ end
18
+
19
+ it "inserts multiple records into the DB in a single insert statement" do
20
+ records = 10.times.map { |i| {:age => 4, :name => "Foo#{i}"} }
21
+
22
+ ActiveRecord::ConnectionAdapters::SQLite3Adapter.any_instance.should_receive(:execute).with do |params|
23
+ matchdata = params.match(/insert into "sample_records"/i)
24
+ matchdata.to_a.count.should == 1
25
+ records.each do |record|
26
+ params.should include(record[:age].to_s)
27
+ params.should include(record[:name])
28
+ end
29
+ end.once
30
+
31
+ SampleRecord.bulk_insert(records)
32
+ end
33
+
34
+ it "relies on the DB to provide primary_key if :use_provided_primary_key is false or nil" do
35
+ records = 10.times.map { |i| SampleRecord.new(:id => 10000 + i, :age => 4, :name => "Foo#{i}") }
36
+
37
+ ActiveRecord::ConnectionAdapters::SQLite3Adapter.any_instance.should_receive(:execute).with do |params|
38
+ records.each do |record|
39
+ params.should_not include(record.id.to_s)
40
+ end
41
+ end
42
+
43
+ SampleRecord.bulk_insert(records)
44
+ end
45
+
46
+ it "uses provided primary_key if :use_provided_primary_key is true" do
47
+ records = 10.times.map { |i| SampleRecord.new(:id => 10000 + i, :age => 4, :name => "Foo#{i}") }
48
+
49
+ SampleRecord.bulk_insert(records, :use_provided_primary_key => true)
50
+ records.each do |record|
51
+ SampleRecord.exists?(:id => record.id).should be_true
52
+ end
53
+ end
54
+
55
+ it "support insertion of ActiveRecord objects" do
56
+ records = 10.times.map { |i| SampleRecord.new(:age => 4, :name => "Foo#{i}") }
57
+
58
+ ActiveRecord::ConnectionAdapters::SQLite3Adapter.any_instance.should_receive(:execute).with do |params|
59
+ matchdata = params.match(/insert into "sample_records"/i)
60
+ matchdata.to_a.count.should == 1
61
+ records.each do |record|
62
+ params.should include(record.age.to_s)
63
+ params.should include(record.name)
64
+ end
65
+ end.once
66
+
67
+ SampleRecord.bulk_insert(records)
68
+ end
69
+
70
+ it "doesn't blow up on an empty array" do
71
+ expect do
72
+ SampleRecord.bulk_insert([])
73
+ end.to_not raise_error
74
+ end
75
+
76
+ context "validations" do
77
+ it "should not persist invalid records if ':validate => true' is specified" do
78
+ SampleRecord.send(:validates, :name, :presence => true)
79
+ expect {SampleRecord.bulk_insert([:age => 30], :validate => true)}.to_not change{SampleRecord.count}
80
+ end
81
+ end
82
+
83
+ context "timestamps" do
84
+ it "sets created_at and updated_at by default" do
85
+ records = 10.times.map { |i| SampleRecord.new(:id => 10000 + i, :age => 4, :name => "Foo#{i}") }
86
+ SampleRecord.bulk_insert(records)
87
+
88
+ SampleRecord.all.each do |record|
89
+ record.created_at.should_not be_nil
90
+ end
91
+ end
92
+
93
+ it "does not set created_at and updated_at if :disable_timestamps is true" do
94
+ records = 10.times.map { |i| SampleRecord.new(:id => 10000 + i, :age => 4, :name => "Foo#{i}") }
95
+ SampleRecord.bulk_insert(records, :disable_timestamps => true)
96
+
97
+ SampleRecord.all.each do |record|
98
+ record.created_at.should be_nil
99
+ end
100
+ end
101
+ end
102
+ end
103
+
104
+ describe "bulk_insert_in_batches" do
105
+ it "allows you to specify a batch_size" do
106
+ records = 10.times.map { |i| SampleRecord.new(:age => 4, :name => "Foo#{i}").attributes }
107
+
108
+ ActiveRecord::ConnectionAdapters::SQLite3Adapter.any_instance.should_receive(:execute).with do |params|
109
+ params.should include("INSERT INTO \"sample_records\"")
110
+ end.exactly(5).times
111
+
112
+ SampleRecord.bulk_insert_in_batches(records, :batch_size => 2)
113
+ end
114
+ end
89
115
  end
@@ -3,6 +3,7 @@ class SampleRecordMigration < ActiveRecord::Migration
3
3
  create_table :sample_records do |t|
4
4
  t.text "name"
5
5
  t.integer "age"
6
+ t.timestamps
6
7
  end
7
8
  end
8
9
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: active_record_bulk_insert
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.1
4
+ version: 1.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Abejide Ayodele
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-05-30 00:00:00.000000000 Z
11
+ date: 2014-07-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
@@ -104,7 +104,7 @@ signing_key:
104
104
  specification_version: 4
105
105
  summary: bulk insert records into the DB
106
106
  test_files:
107
+ - spec/support/sample_record.rb
108
+ - spec/support/migrations/1_sample_record_migration.rb
107
109
  - spec/sample_record_spec.rb
108
110
  - spec/spec_helper.rb
109
- - spec/support/migrations/1_sample_record_migration.rb
110
- - spec/support/sample_record.rb