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 CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- NzYyYTU1NDY4N2VhZDdhNjlmNmQ2NjViMGQ0MThmMjIwNmU4ZGVhNg==
4
+ ZTU5ZWUwYzkwMDExYjE2MTIyNzJiOWJmMzhkZDA5YzQ1ZmNiMGNmMA==
5
5
  data.tar.gz: !binary |-
6
- ZjVkMDU0N2IwNmI1YTAyZTE0YTgwOGFkYjkyN2FhNWVhNzc2OTAwZg==
6
+ YWNhZjgzZWQ5MWQ1MzYyZmEwOTlmZjA0ZTMwZTg3MDA1M2U5NGY0Mg==
7
7
  SHA512:
8
8
  metadata.gz: !binary |-
9
- MzZkNDY0MjUzNjZhNjcwYzRlOTE3ZTMwYWVhMmVhMjQ0ZGU3ZjQ4YWUzMmQ2
10
- N2M2MThmNWI1YTZkOTZhMDNlM2M0NTBlYmZjYjcxODRlYzAxYzkwMmMwYTMw
11
- NTBkN2I2MmFjYmE5YzY2NmI2YjljOTkyYzk2ODBkZjNmOGM2YmE=
9
+ ODJhZWIzNTk2MTM2ZGQ5ZDljODY1NzAyNDMwYTljMmU1MDJiZTc1ZmFiZjQ3
10
+ ZWYxOTFiYzJhYTFhYmI1OTU1Y2I4NmM3NDI4ZTdjYzVhZjMzMjkwYjlkZGEx
11
+ MzFiYzFmYzZmMDllYjYwZjZkMWM0Zjg1NDQ5YTA5ZjlhYzE4OGI=
12
12
  data.tar.gz: !binary |-
13
- MzJiNWViODk5MzlmOTRkNzU0MTJhZTdkMWRmMGY4YTg3YTVlN2FmYTEzZGRj
14
- ZWViMTMyZGY2NGNjY2I1OTAxM2Q1ZWRjYTUyNzU1ZDI1NGMwYzcwZmI0YjMw
15
- OGQxZjUwZGUyMzUzNTU0NTVkMTVjOTM1OTI2NDQ4MGFiYjgzYmY=
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 )
@@ -0,0 +1,6 @@
1
+ test:
2
+ adapter: mysql2
3
+ encoding: utf8
4
+ database: mass_updater_test
5
+ username: root
6
+ password:
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
- self.connection.execute(sql)
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
- self.connection.execute(sql)
25
+ ActiveRecord::Base.connection.execute(sql)
26
26
  end
27
27
  end
28
28
 
@@ -1,3 +1,3 @@
1
1
  module MassUpdater
2
- VERSION = "0.0.1"
2
+ VERSION = "0.0.2"
3
3
  end
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
@@ -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.1
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-05 00:00:00.000000000 Z
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.2
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
- has_rdoc:
126
+ test_files:
127
+ - spec/insert_or_update.rb
128
+ - spec/spec_helper.rb