mass_updater 0.0.1 → 0.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 +8 -8
- data/README.md +43 -0
- data/config/database.yml +6 -0
- data/lib/mass_updater.rb +2 -2
- data/lib/mass_updater/version.rb +1 -1
- data/mass_updater.gemspec +3 -0
- data/spec/insert_or_update.rb +28 -0
- data/spec/spec_helper.rb +43 -0
- metadata +51 -5
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
ZTU5ZWUwYzkwMDExYjE2MTIyNzJiOWJmMzhkZDA5YzQ1ZmNiMGNmMA==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
YWNhZjgzZWQ5MWQ1MzYyZmEwOTlmZjA0ZTMwZTg3MDA1M2U5NGY0Mg==
|
7
7
|
SHA512:
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
ODJhZWIzNTk2MTM2ZGQ5ZDljODY1NzAyNDMwYTljMmU1MDJiZTc1ZmFiZjQ3
|
10
|
+
ZWYxOTFiYzJhYTFhYmI1OTU1Y2I4NmM3NDI4ZTdjYzVhZjMzMjkwYjlkZGEx
|
11
|
+
MzFiYzFmYzZmMDllYjYwZjZkMWM0Zjg1NDQ5YTA5ZjlhYzE4OGI=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
YTVjMGFkNjVlZWMyMzMxZDQyZTk2NWQyYWFhMmJjOGQzMWRmNGFkMzE0N2Vk
|
14
|
+
NDVmYWEwODhhM2U3YWFlOTNjYzhjMGZhYjA2ZGIwMmQwNGI0NzdmYTQ2NGE2
|
15
|
+
NzY1ZWI2ZmYwMTBlMzY4NTY0OGUzNTAzZTQzZTM1N2ExMWUxODg=
|
data/README.md
CHANGED
@@ -50,6 +50,49 @@ The following example with run one mysql query rather than thousands:
|
|
50
50
|
end
|
51
51
|
end
|
52
52
|
|
53
|
+
If you don't care to update existing rows, and you wish to discard any unique key violations silently, you may use the 'insert_ignore' method. It works exactly the same as 'insert_or_update', but the 4th parameter is no longer necessary.
|
54
|
+
Here is the former example using 'insert_ignore' instead:
|
55
|
+
|
56
|
+
class Stat < ActiveRecord::Base
|
57
|
+
extend MassUpdater
|
58
|
+
|
59
|
+
def record_rows
|
60
|
+
stat_inserts = []
|
61
|
+
|
62
|
+
rows = OtherObject.pull_thousands_of_rows_of_data_from_a_some_source()
|
63
|
+
rows.each do |row|
|
64
|
+
stat_inserts << "'#{self.connection.quote_string(row[:name])}', #{row[:id]}, '#{row[:status]}', #{row[:metric]}, NOW(), NOW()"
|
65
|
+
end
|
66
|
+
self.insert_ignore('stats', [:name, :api_id, :status, :metric, :created_at, :updated_at], adgroup_inserts)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
It is very common in my workflow to need to translate from an external API's ID to my ActiveRecord ID when setting up foreign keys. I've included a "build_api_hash" method to help with this translation.
|
71
|
+
It returns a simple hash, mapping the api_id to id.
|
72
|
+
Once again, the method will do it's work with one hit to the database rather than thousands. An extended example is below:
|
73
|
+
|
74
|
+
class LineItem < ActiveRecord::Base
|
75
|
+
has_many :stats
|
76
|
+
end
|
77
|
+
|
78
|
+
class Stat < ActiveRecord::Base
|
79
|
+
belongs_to :line_item
|
80
|
+
extend MassUpdater
|
81
|
+
|
82
|
+
def record_rows
|
83
|
+
stat_inserts = []
|
84
|
+
line_item_ids = rpt.map{|r| r[:line_item_api_id]}.uniq.compact
|
85
|
+
line_item_hash = self.build_api_hash(LineItem, 'api_id', line_item_ids)
|
86
|
+
|
87
|
+
rows = OtherObject.pull_thousands_of_rows_of_data_from_a_some_source()
|
88
|
+
rows.each do |row|
|
89
|
+
stat_inserts << "'#{self.connection.quote_string(row[:name])}', #{row[:id]}, #{line_item_hash[row[:id]]}, '#{row[:status]}', #{row[:metric]}, NOW(), NOW()"
|
90
|
+
end
|
91
|
+
self.insert_or_update('stats', [:name, :api_id, :line_item_id, :status, :metric, :created_at, :updated_at], adgroup_inserts, [:name, :status, :metric, :updated_at])
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
|
53
96
|
## Contributing
|
54
97
|
|
55
98
|
1. Fork it ( https://github.com/KarateCode/mass_updater/fork )
|
data/config/database.yml
ADDED
data/lib/mass_updater.rb
CHANGED
@@ -12,7 +12,7 @@ module MassUpdater
|
|
12
12
|
VALUES (#{inserts.join("),\n(")})
|
13
13
|
ON DUPLICATE KEY UPDATE
|
14
14
|
#{update_sql.join(", ")};"
|
15
|
-
|
15
|
+
ActiveRecord::Base.connection.execute(sql)
|
16
16
|
end
|
17
17
|
end
|
18
18
|
|
@@ -22,7 +22,7 @@ ON DUPLICATE KEY UPDATE
|
|
22
22
|
|
23
23
|
sql = "INSERT IGNORE INTO #{table_name} (`#{record_fields.join('`, `')}`)
|
24
24
|
VALUES (#{inserts.join("),\n(")});"
|
25
|
-
|
25
|
+
ActiveRecord::Base.connection.execute(sql)
|
26
26
|
end
|
27
27
|
end
|
28
28
|
|
data/lib/mass_updater/version.rb
CHANGED
data/mass_updater.gemspec
CHANGED
@@ -19,5 +19,8 @@ Gem::Specification.new do |spec|
|
|
19
19
|
spec.require_paths = ["lib"]
|
20
20
|
|
21
21
|
spec.add_development_dependency "bundler", "~> 1.6"
|
22
|
+
spec.add_development_dependency "rspec"
|
23
|
+
spec.add_development_dependency 'database_cleaner'
|
24
|
+
spec.add_development_dependency 'mysql2'
|
22
25
|
spec.add_development_dependency "activerecord", "~> 3.2"
|
23
26
|
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), *%w[spec_helper])
|
2
|
+
|
3
|
+
class LineItem < ActiveRecord::Base
|
4
|
+
has_many :stats
|
5
|
+
end
|
6
|
+
|
7
|
+
class Stat < ActiveRecord::Base
|
8
|
+
belongs_to :line_item
|
9
|
+
extend MassUpdater
|
10
|
+
|
11
|
+
def record_rows
|
12
|
+
stat_inserts = []
|
13
|
+
line_item_ids = rpt.map{|r| r[:line_item_api_id]}.uniq.compact
|
14
|
+
line_item_hash = self.build_api_hash(LineItem, 'api_id', line_item_ids)
|
15
|
+
|
16
|
+
rows = OtherObject.pull_thousands_of_rows_of_data_from_a_some_source()
|
17
|
+
rows.each do |row|
|
18
|
+
stat_inserts << "'#{self.connection.quote_string(row[:name])}', #{row[:id]}, #{line_item_hash[row[:id]]}, '#{row[:status]}', #{row[:metric]}, NOW(), NOW()"
|
19
|
+
end
|
20
|
+
self.insert_or_update('stats', [:name, :api_id, :line_item_id, :status, :metric, :created_at, :updated_at], adgroup_inserts, [:name, :status, :metric, :updated_at])
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
describe ".insert_or_update" do
|
25
|
+
it "should do something..." do
|
26
|
+
|
27
|
+
end
|
28
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
gemfile = File.expand_path('../../Gemfile', __FILE__)
|
2
|
+
begin
|
3
|
+
ENV['BUNDLE_GEMFILE'] = gemfile
|
4
|
+
require 'bundler'
|
5
|
+
Bundler.setup
|
6
|
+
puts "bundler is set up"
|
7
|
+
rescue Bundler::GemNotFound => e
|
8
|
+
STDERR.puts e.message
|
9
|
+
STDERR.puts "Try running `bundle install`."
|
10
|
+
exit!
|
11
|
+
end if File.exist?(gemfile)
|
12
|
+
|
13
|
+
require 'active_record'
|
14
|
+
require 'database_cleaner'
|
15
|
+
|
16
|
+
DB = YAML::load(File.open('config/database.yml'))
|
17
|
+
ActiveRecord::Base.establish_connection(DB["test"])
|
18
|
+
|
19
|
+
RSpec.configure do |config|
|
20
|
+
# config.include Capybara::DSL
|
21
|
+
|
22
|
+
config.mock_with :rspec
|
23
|
+
|
24
|
+
# Remove this line if you're not using ActiveRecord or ActiveRecord fixtures
|
25
|
+
# config.fixture_path = "#{::Rails.root}/spec/fixtures"
|
26
|
+
|
27
|
+
# If you're not using ActiveRecord, or you'd prefer not to run each of your
|
28
|
+
# examples within a transaction, remove the following line or assign false
|
29
|
+
# instead of true.
|
30
|
+
# config.use_transactional_fixtures = false
|
31
|
+
|
32
|
+
config.before(:suite) do
|
33
|
+
DatabaseCleaner.strategy = :truncation
|
34
|
+
end
|
35
|
+
|
36
|
+
config.before(:each) do
|
37
|
+
DatabaseCleaner.start
|
38
|
+
end
|
39
|
+
|
40
|
+
config.after(:each) do
|
41
|
+
DatabaseCleaner.clean
|
42
|
+
end
|
43
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mass_updater
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Michael Schneider
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-11-
|
11
|
+
date: 2014-11-24 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -24,6 +24,48 @@ dependencies:
|
|
24
24
|
- - ~>
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '1.6'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rspec
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ! '>='
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ! '>='
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: database_cleaner
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ! '>='
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ! '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: mysql2
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ! '>='
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
27
69
|
- !ruby/object:Gem::Dependency
|
28
70
|
name: activerecord
|
29
71
|
requirement: !ruby/object:Gem::Requirement
|
@@ -51,9 +93,12 @@ files:
|
|
51
93
|
- LICENSE.txt
|
52
94
|
- README.md
|
53
95
|
- Rakefile
|
96
|
+
- config/database.yml
|
54
97
|
- lib/mass_updater.rb
|
55
98
|
- lib/mass_updater/version.rb
|
56
99
|
- mass_updater.gemspec
|
100
|
+
- spec/insert_or_update.rb
|
101
|
+
- spec/spec_helper.rb
|
57
102
|
homepage: https://github.com/KarateCode/mass_updater
|
58
103
|
licenses:
|
59
104
|
- MIT
|
@@ -74,9 +119,10 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
74
119
|
version: '0'
|
75
120
|
requirements: []
|
76
121
|
rubyforge_project:
|
77
|
-
rubygems_version: 2.4.
|
122
|
+
rubygems_version: 2.4.3
|
78
123
|
signing_key:
|
79
124
|
specification_version: 4
|
80
125
|
summary: Bulk updating and inserting of records for ActiveRecord and mysql
|
81
|
-
test_files:
|
82
|
-
|
126
|
+
test_files:
|
127
|
+
- spec/insert_or_update.rb
|
128
|
+
- spec/spec_helper.rb
|