active_record_bulk_insert 1.0.1 → 1.0.2

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: 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