upsert 0.3.4 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (51) hide show
  1. data/CHANGELOG +12 -0
  2. data/README.md +6 -9
  3. data/Rakefile +9 -14
  4. data/lib/upsert.rb +40 -71
  5. data/lib/upsert/buffer.rb +36 -0
  6. data/lib/upsert/buffer/mysql2_client.rb +67 -0
  7. data/lib/upsert/buffer/pg_connection.rb +54 -0
  8. data/lib/upsert/buffer/pg_connection/merge_function.rb +138 -0
  9. data/lib/upsert/buffer/sqlite3_database.rb +13 -0
  10. data/lib/upsert/connection.rb +41 -0
  11. data/lib/upsert/connection/mysql2_client.rb +53 -0
  12. data/lib/upsert/connection/pg_connection.rb +39 -0
  13. data/lib/upsert/connection/sqlite3_database.rb +36 -0
  14. data/lib/upsert/row.rb +28 -24
  15. data/lib/upsert/version.rb +1 -1
  16. data/spec/active_record_upsert_spec.rb +16 -0
  17. data/spec/binary_spec.rb +21 -0
  18. data/spec/correctness_spec.rb +73 -0
  19. data/spec/database_functions_spec.rb +36 -0
  20. data/spec/database_spec.rb +97 -0
  21. data/spec/logger_spec.rb +37 -0
  22. data/{test → spec}/misc/get_postgres_reserved_words.rb +0 -0
  23. data/{test → spec}/misc/mysql_reserved.txt +0 -0
  24. data/{test → spec}/misc/pg_reserved.txt +0 -0
  25. data/spec/multibyte_spec.rb +27 -0
  26. data/spec/precision_spec.rb +11 -0
  27. data/spec/reserved_words_spec.rb +46 -0
  28. data/{test/helper.rb → spec/spec_helper.rb} +43 -43
  29. data/spec/speed_spec.rb +73 -0
  30. data/spec/threaded_spec.rb +34 -0
  31. data/spec/timezones_spec.rb +28 -0
  32. data/upsert.gemspec +6 -2
  33. metadata +99 -50
  34. data/lib/upsert/mysql2_client.rb +0 -104
  35. data/lib/upsert/pg_connection.rb +0 -92
  36. data/lib/upsert/pg_connection/column_definition.rb +0 -35
  37. data/lib/upsert/sqlite3_database.rb +0 -39
  38. data/test/shared/binary.rb +0 -18
  39. data/test/shared/correctness.rb +0 -72
  40. data/test/shared/database.rb +0 -94
  41. data/test/shared/multibyte.rb +0 -37
  42. data/test/shared/precision.rb +0 -8
  43. data/test/shared/reserved_words.rb +0 -45
  44. data/test/shared/speed.rb +0 -72
  45. data/test/shared/threaded.rb +0 -31
  46. data/test/shared/timezones.rb +0 -25
  47. data/test/test_active_record_connection_adapter.rb +0 -36
  48. data/test/test_active_record_upsert.rb +0 -23
  49. data/test/test_mysql2.rb +0 -43
  50. data/test/test_pg.rb +0 -45
  51. data/test/test_sqlite.rb +0 -47
@@ -0,0 +1,37 @@
1
+ require 'spec_helper'
2
+ describe Upsert do
3
+ describe "logger" do
4
+ it "logs to stderr by default" do
5
+ begin
6
+ old_stderr = $stderr
7
+ old_logger = Upsert.logger
8
+ Upsert.logger = nil
9
+ $stderr = StringIO.new
10
+ Upsert.logger.warn "hello"
11
+ $stderr.rewind
12
+ $stderr.read.chomp.should == 'hello'
13
+ ensure
14
+ Upsert.logger = old_logger
15
+ $stderr = old_stderr
16
+ end
17
+ end
18
+
19
+ it "logs queries" do
20
+ require 'sqlite3'
21
+ db = SQLite3::Database.open(':memory:')
22
+ db.execute_batch "CREATE TABLE cats (name CHARACTER VARYING(255))"
23
+ begin
24
+ io = StringIO.new
25
+ old_logger = Upsert.logger
26
+ Upsert.logger = Logger.new io, Logger::DEBUG
27
+ u = Upsert.new(db, :cats)
28
+ u.row :name => 'you'
29
+ io.rewind
30
+ io.read.chomp.should =~ /INSERT OR IGNORE.*you/i
31
+ ensure
32
+ Upsert.logger = old_logger
33
+ end
34
+ end
35
+
36
+ end
37
+ end
File without changes
File without changes
File without changes
@@ -0,0 +1,27 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require 'spec_helper'
3
+ describe Upsert do
4
+ describe "supports multibyte" do
5
+ it "works one-by-one" do
6
+ assert_creates(Pet, [{:name => 'I♥NY', :gender => 'périferôl'}]) do
7
+ upsert = Upsert.new $conn, :pets
8
+ upsert.row({:name => 'I♥NY'}, {:gender => 'périferôl'})
9
+ end
10
+ end
11
+ it "works serially" do
12
+ assert_creates(Pet, [{:name => 'I♥NY', :gender => 'jÚrgen'}]) do
13
+ upsert = Upsert.new $conn, :pets
14
+ upsert.row({:name => 'I♥NY'}, {:gender => 'périferôl'})
15
+ upsert.row({:name => 'I♥NY'}, {:gender => 'jÚrgen'})
16
+ end
17
+ end
18
+ it "works batch" do
19
+ assert_creates(Pet, [{:name => 'I♥NY', :gender => 'jÚrgen'}]) do
20
+ Upsert.batch($conn, :pets) do |upsert|
21
+ upsert.row({:name => 'I♥NY'}, {:gender => 'périferôl'})
22
+ upsert.row({:name => 'I♥NY'}, {:gender => 'jÚrgen'})
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,11 @@
1
+ require 'spec_helper'
2
+ describe Upsert do
3
+ describe "is precise" do
4
+ it "stores small numbers precisely" do
5
+ small = -0.00000000634943
6
+ upsert = Upsert.new $conn, :pets
7
+ upsert.row({:name => 'NotJerry'}, :lovability => small)
8
+ Pet.first.lovability.should == small
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,46 @@
1
+ require 'spec_helper'
2
+ describe Upsert do
3
+ describe "doesn't blow up on reserved words" do
4
+ # collect and uniq reserved words
5
+ reserved_words = ['mysql_reserved.txt', 'pg_reserved.txt'].map do |basename|
6
+ File.expand_path("../misc/#{basename}", __FILE__)
7
+ end.map do |path|
8
+ IO.readlines(path)
9
+ end.flatten.map(&:chomp).select(&:present?).uniq
10
+
11
+ # make lots of AR models, each of which has 10 columns named after these words
12
+ nasties = []
13
+ reserved_words.each_slice(10) do |words|
14
+ eval %{
15
+ class Nasty#{nasties.length} < ActiveRecord::Base
16
+ end
17
+ }
18
+ nasty = Object.const_get("Nasty#{nasties.length}")
19
+ nasty.class_eval do
20
+ self.primary_key = 'fake_primary_key'
21
+ col :fake_primary_key
22
+ words.each do |word|
23
+ col word
24
+ end
25
+ end
26
+ nasties << [ nasty, words ]
27
+ end
28
+ nasties.each do |nasty, _|
29
+ nasty.auto_upgrade!
30
+ end
31
+
32
+ describe "reserved words" do
33
+ nasties.each do |nasty, words|
34
+ it "doesn't die on reserved words #{words.join(',')}" do
35
+ upsert = Upsert.new $conn, nasty.table_name
36
+ random = rand(1e3).to_s
37
+ selector = { :fake_primary_key => random, words.first => words.first }
38
+ document = words[1..-1].inject({}) { |memo, word| memo[word] = word; memo }
39
+ assert_creates nasty, [selector.merge(document)] do
40
+ upsert.row selector, document
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
@@ -1,22 +1,34 @@
1
- require 'rubygems'
2
1
  require 'bundler/setup'
3
- require 'securerandom'
4
- require 'zlib'
5
- require 'benchmark'
6
- require 'faker'
7
- require 'minitest/spec'
8
- require 'minitest/autorun'
9
- require 'minitest/reporters'
10
- MiniTest::Unit.runner = MiniTest::SuiteRunner.new
11
- MiniTest::Unit.runner.reporters << MiniTest::Reporters::SpecReporter.new
12
2
 
13
3
  require 'active_record'
14
- require 'activerecord-import'
15
4
  require 'active_record_inline_schema'
5
+ require 'activerecord-import'
16
6
 
17
- # require 'logger'
18
- # ActiveRecord::Base.logger = Logger.new($stdout)
19
- # ActiveRecord::Base.logger.level = Logger::DEBUG
7
+ ENV['ADAPTER'] ||= 'mysql2'
8
+
9
+ case ENV['ADAPTER']
10
+ when 'postgresql'
11
+ system %{ dropdb upsert_test }
12
+ system %{ createdb upsert_test }
13
+ ActiveRecord::Base.establish_connection :adapter => 'postgresql', :database => 'upsert_test'
14
+ $conn = PGconn.new(:dbname => 'upsert_test')
15
+ when 'mysql2'
16
+ system %{ mysql -u root -ppassword -e "DROP DATABASE IF EXISTS upsert_test" }
17
+ system %{ mysql -u root -ppassword -e "CREATE DATABASE upsert_test CHARSET utf8" }
18
+ ActiveRecord::Base.establish_connection 'mysql2://root:password@127.0.0.1/upsert_test'
19
+ $conn = Mysql2::Client.new(:username => 'root', :password => 'password', :database => 'upsert_test')
20
+ when 'sqlite3'
21
+ ActiveRecord::Base.establish_connection :adapter => 'sqlite3', :database => ':memory:'
22
+ $conn = ActiveRecord::Base.connection.raw_connection
23
+ else
24
+ raise "not supported"
25
+ end
26
+
27
+ if ENV['UPSERT_DEBUG'] == 'true'
28
+ require 'logger'
29
+ ActiveRecord::Base.logger = Logger.new($stdout)
30
+ ActiveRecord::Base.logger.level = Logger::DEBUG
31
+ end
20
32
 
21
33
  class Pet < ActiveRecord::Base
22
34
  col :name
@@ -31,16 +43,14 @@ class Pet < ActiveRecord::Base
31
43
  col :home_address, :type => :text
32
44
  add_index :name, :unique => true
33
45
  end
46
+ Pet.auto_upgrade!
34
47
 
35
- # ENV['UPSERT_DEBUG'] = 'true'
36
-
37
- require 'upsert'
38
-
39
- MiniTest::Spec.class_eval do
40
- def self.shared_examples
41
- @shared_examples ||= {}
42
- end
48
+ require 'securerandom'
49
+ require 'zlib'
50
+ require 'benchmark'
51
+ require 'faker'
43
52
 
53
+ module SpecHelper
44
54
  def lotsa_records
45
55
  @records ||= begin
46
56
  memo = []
@@ -77,22 +87,22 @@ MiniTest::Spec.class_eval do
77
87
 
78
88
  Pet.delete_all
79
89
 
80
- Upsert.batch(connection, :pets) do |upsert|
90
+ Upsert.batch($conn, :pets) do |upsert|
81
91
  records.each do |selector, document|
82
92
  upsert.row(selector, document)
83
93
  end
84
94
  end
85
95
  ref2 = Pet.order(:name).all.map { |pet| pet.attributes.except('id') }
86
- ref2.must_equal ref1
96
+ ref2.should == ref1
87
97
  end
88
98
 
89
99
  def assert_creates(model, expected_records)
90
100
  expected_records.each do |conditions|
91
- model.where(conditions).count.must_equal 0
101
+ model.where(conditions).count.should == 0
92
102
  end
93
103
  yield
94
104
  expected_records.each do |conditions|
95
- model.where(conditions).count.must_equal 1
105
+ model.where(conditions).count.should == 1
96
106
  end
97
107
  end
98
108
 
@@ -109,32 +119,22 @@ MiniTest::Spec.class_eval do
109
119
  sleep 1
110
120
 
111
121
  upsert_time = Benchmark.realtime do
112
- Upsert.batch(connection, :pets) do |upsert|
122
+ Upsert.batch($conn, :pets) do |upsert|
113
123
  records.each do |selector, document|
114
124
  upsert.row(selector, document)
115
125
  end
116
126
  end
117
127
  end
118
- upsert_time.must_be :<, ar_time
128
+ upsert_time.should be < ar_time
119
129
  $stderr.puts " Upsert was #{((ar_time - upsert_time) / ar_time * 100).round}% faster than #{competition}"
120
130
  end
121
131
  end
122
132
 
123
- module MiniTest::Spec::SharedExamples
124
- def shared_examples_for(desc, &block)
125
- MiniTest::Spec.shared_examples[desc] = block
126
- end
127
-
128
- def it_also(desc)
129
- self.instance_eval(&MiniTest::Spec.shared_examples[desc])# do
130
- # describe desc do
131
- # .call
132
- # end
133
- # end
133
+ RSpec.configure do |c|
134
+ c.include SpecHelper
135
+ c.before do
136
+ Pet.delete_all
134
137
  end
135
138
  end
136
139
 
137
- Object.class_eval { include(MiniTest::Spec::SharedExamples) }
138
- Dir[File.expand_path("../shared/*.rb", __FILE__)].each do |path|
139
- require path
140
- end
140
+ require 'upsert'
@@ -0,0 +1,73 @@
1
+ require 'spec_helper'
2
+ describe Upsert do
3
+ describe "can be speeded up with upserting" do
4
+ describe 'compared to native ActiveRecord' do
5
+ it "is faster than new/set/save" do
6
+ assert_faster_than 'find + new/set/save', lotsa_records do |records|
7
+ records.each do |selector, document|
8
+ if pet = Pet.where(selector).first
9
+ pet.update_attributes document, :without_protection => true
10
+ else
11
+ pet = Pet.new
12
+ selector.each do |k, v|
13
+ pet.send "#{k}=", v
14
+ end
15
+ document.each do |k, v|
16
+ pet.send "#{k}=", v
17
+ end
18
+ pet.save!
19
+ end
20
+ end
21
+ end
22
+ end
23
+ it "is faster than find_or_create + update_attributes" do
24
+ assert_faster_than 'find_or_create + update_attributes', lotsa_records do |records|
25
+ dynamic_method = nil
26
+ records.each do |selector, document|
27
+ dynamic_method ||= "find_or_create_by_#{selector.keys.join('_or_')}"
28
+ pet = Pet.send(dynamic_method, *selector.values)
29
+ pet.update_attributes document, :without_protection => true
30
+ end
31
+ end
32
+ end
33
+ it "is faster than create + rescue/find/update" do
34
+ assert_faster_than 'create + rescue/find/update', lotsa_records do |records|
35
+ dynamic_method = nil
36
+ records.each do |selector, document|
37
+ dynamic_method ||= "find_or_create_by_#{selector.keys.join('_or_')}"
38
+ begin
39
+ Pet.create selector.merge(document), :without_protection => true
40
+ rescue
41
+ pet = Pet.send(dynamic_method, *selector.values)
42
+ pet.update_attributes document, :without_protection => true
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
48
+
49
+ if ENV['ADAPTER'] == 'mysql2'
50
+ describe 'compared to activerecord-import' do
51
+ it "is faster than faking upserts with activerecord-import" do
52
+ assert_faster_than 'faking upserts with activerecord-import', lotsa_records do |records|
53
+ columns = nil
54
+ all_values = []
55
+ records.each do |selector, document|
56
+ columns ||= (selector.keys + document.keys).uniq
57
+ all_values << columns.map do |k|
58
+ if document.has_key?(k)
59
+ # prefer the document so that you can change rows
60
+ document[k]
61
+ else
62
+ selector[k]
63
+ end
64
+ end
65
+ end
66
+ Pet.import columns, all_values, :timestamps => false, :on_duplicate_key_update => columns
67
+ end
68
+ end
69
+ end
70
+ end
71
+
72
+ end
73
+ end
@@ -0,0 +1,34 @@
1
+ require 'spec_helper'
2
+ describe Upsert do
3
+ describe "is thread-safe" do
4
+ it "is safe to use one-by-one" do
5
+ upsert = Upsert.new $conn, :pets
6
+ assert_creates(Pet, [{:name => 'Jerry', :gender => 'neutered'}]) do
7
+ ts = []
8
+ 10.times do
9
+ ts << Thread.new do
10
+ sleep 0.2
11
+ upsert.row({:name => 'Jerry'}, :gender => 'male')
12
+ upsert.row({:name => 'Jerry'}, :gender => 'neutered')
13
+ end
14
+ ts.each { |t| t.join }
15
+ end
16
+ end
17
+ end
18
+ it "is safe to use batch" do
19
+ assert_creates(Pet, [{:name => 'Jerry', :gender => 'neutered'}]) do
20
+ Upsert.batch($conn, :pets) do |upsert|
21
+ ts = []
22
+ 10.times do
23
+ ts << Thread.new do
24
+ sleep 0.2
25
+ upsert.row({:name => 'Jerry'}, :gender => 'male')
26
+ upsert.row({:name => 'Jerry'}, :gender => 'neutered')
27
+ end
28
+ ts.each { |t| t.join }
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,28 @@
1
+ require 'spec_helper'
2
+ describe Upsert do
3
+ describe "doesn't mess with timezones" do
4
+ before do
5
+ @old_default_tz = ActiveRecord::Base.default_timezone
6
+ end
7
+ after do
8
+ ActiveRecord::Base.default_timezone = @old_default_tz
9
+ end
10
+
11
+ it "deals fine with UTC" do
12
+ ActiveRecord::Base.default_timezone = :utc
13
+ time = Time.now.utc
14
+ upsert = Upsert.new $conn, :pets
15
+ assert_creates(Pet, [{:name => 'Jerry', :morning_walk_time => time}]) do
16
+ upsert.row({:name => 'Jerry'}, {:morning_walk_time => time})
17
+ end
18
+ end
19
+ it "won't mess with UTC" do
20
+ ActiveRecord::Base.default_timezone = :local
21
+ time = Time.now
22
+ upsert = Upsert.new $conn, :pets
23
+ assert_creates(Pet, [{:name => 'Jerry', :morning_walk_time => time}]) do
24
+ upsert.row({:name => 'Jerry'}, {:morning_walk_time => time})
25
+ end
26
+ end
27
+ end
28
+ end
data/upsert.gemspec CHANGED
@@ -15,14 +15,18 @@ Gem::Specification.new do |gem|
15
15
  gem.require_paths = ["lib"]
16
16
  gem.version = Upsert::VERSION
17
17
 
18
+ gem.add_development_dependency 'posix-spawn'
19
+ gem.add_development_dependency 'rspec-core'
20
+ gem.add_development_dependency 'rspec-expectations'
21
+ gem.add_development_dependency 'rspec-mocks'
22
+
18
23
  gem.add_development_dependency 'sqlite3'
19
24
  gem.add_development_dependency 'mysql2'
20
25
  gem.add_development_dependency 'pg'
21
26
  gem.add_development_dependency 'activerecord' # testing only
22
27
  gem.add_development_dependency 'active_record_inline_schema'
23
28
  gem.add_development_dependency 'faker'
24
- gem.add_development_dependency 'minitest'
25
- gem.add_development_dependency 'minitest-reporters'
26
29
  gem.add_development_dependency 'yard'
27
30
  gem.add_development_dependency 'activerecord-import'
31
+ gem.add_development_dependency 'pry'
28
32
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: upsert
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.4
4
+ version: 0.4.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,10 +9,10 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-07-03 00:00:00.000000000 Z
12
+ date: 2012-09-04 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
- name: sqlite3
15
+ name: posix-spawn
16
16
  requirement: !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
@@ -28,7 +28,7 @@ dependencies:
28
28
  - !ruby/object:Gem::Version
29
29
  version: '0'
30
30
  - !ruby/object:Gem::Dependency
31
- name: mysql2
31
+ name: rspec-core
32
32
  requirement: !ruby/object:Gem::Requirement
33
33
  none: false
34
34
  requirements:
@@ -44,7 +44,7 @@ dependencies:
44
44
  - !ruby/object:Gem::Version
45
45
  version: '0'
46
46
  - !ruby/object:Gem::Dependency
47
- name: pg
47
+ name: rspec-expectations
48
48
  requirement: !ruby/object:Gem::Requirement
49
49
  none: false
50
50
  requirements:
@@ -60,7 +60,7 @@ dependencies:
60
60
  - !ruby/object:Gem::Version
61
61
  version: '0'
62
62
  - !ruby/object:Gem::Dependency
63
- name: activerecord
63
+ name: rspec-mocks
64
64
  requirement: !ruby/object:Gem::Requirement
65
65
  none: false
66
66
  requirements:
@@ -76,7 +76,7 @@ dependencies:
76
76
  - !ruby/object:Gem::Version
77
77
  version: '0'
78
78
  - !ruby/object:Gem::Dependency
79
- name: active_record_inline_schema
79
+ name: sqlite3
80
80
  requirement: !ruby/object:Gem::Requirement
81
81
  none: false
82
82
  requirements:
@@ -92,7 +92,7 @@ dependencies:
92
92
  - !ruby/object:Gem::Version
93
93
  version: '0'
94
94
  - !ruby/object:Gem::Dependency
95
- name: faker
95
+ name: mysql2
96
96
  requirement: !ruby/object:Gem::Requirement
97
97
  none: false
98
98
  requirements:
@@ -108,7 +108,7 @@ dependencies:
108
108
  - !ruby/object:Gem::Version
109
109
  version: '0'
110
110
  - !ruby/object:Gem::Dependency
111
- name: minitest
111
+ name: pg
112
112
  requirement: !ruby/object:Gem::Requirement
113
113
  none: false
114
114
  requirements:
@@ -124,7 +124,39 @@ dependencies:
124
124
  - !ruby/object:Gem::Version
125
125
  version: '0'
126
126
  - !ruby/object:Gem::Dependency
127
- name: minitest-reporters
127
+ name: activerecord
128
+ requirement: !ruby/object:Gem::Requirement
129
+ none: false
130
+ requirements:
131
+ - - ! '>='
132
+ - !ruby/object:Gem::Version
133
+ version: '0'
134
+ type: :development
135
+ prerelease: false
136
+ version_requirements: !ruby/object:Gem::Requirement
137
+ none: false
138
+ requirements:
139
+ - - ! '>='
140
+ - !ruby/object:Gem::Version
141
+ version: '0'
142
+ - !ruby/object:Gem::Dependency
143
+ name: active_record_inline_schema
144
+ requirement: !ruby/object:Gem::Requirement
145
+ none: false
146
+ requirements:
147
+ - - ! '>='
148
+ - !ruby/object:Gem::Version
149
+ version: '0'
150
+ type: :development
151
+ prerelease: false
152
+ version_requirements: !ruby/object:Gem::Requirement
153
+ none: false
154
+ requirements:
155
+ - - ! '>='
156
+ - !ruby/object:Gem::Version
157
+ version: '0'
158
+ - !ruby/object:Gem::Dependency
159
+ name: faker
128
160
  requirement: !ruby/object:Gem::Requirement
129
161
  none: false
130
162
  requirements:
@@ -171,6 +203,22 @@ dependencies:
171
203
  - - ! '>='
172
204
  - !ruby/object:Gem::Version
173
205
  version: '0'
206
+ - !ruby/object:Gem::Dependency
207
+ name: pry
208
+ requirement: !ruby/object:Gem::Requirement
209
+ none: false
210
+ requirements:
211
+ - - ! '>='
212
+ - !ruby/object:Gem::Version
213
+ version: '0'
214
+ type: :development
215
+ prerelease: false
216
+ version_requirements: !ruby/object:Gem::Requirement
217
+ none: false
218
+ requirements:
219
+ - - ! '>='
220
+ - !ruby/object:Gem::Version
221
+ version: '0'
174
222
  description: Upsert for MySQL, PostgreSQL, and SQLite. Codifies various SQL MERGE
175
223
  tricks like MySQL's ON DUPLICATE KEY UPDATE, PostgreSQL's CREATE FUNCTION merge_db,
176
224
  and SQLite's INSERT OR IGNORE.
@@ -190,30 +238,33 @@ files:
190
238
  - lib/upsert.rb
191
239
  - lib/upsert/active_record_upsert.rb
192
240
  - lib/upsert/binary.rb
193
- - lib/upsert/mysql2_client.rb
194
- - lib/upsert/pg_connection.rb
195
- - lib/upsert/pg_connection/column_definition.rb
241
+ - lib/upsert/buffer.rb
242
+ - lib/upsert/buffer/mysql2_client.rb
243
+ - lib/upsert/buffer/pg_connection.rb
244
+ - lib/upsert/buffer/pg_connection/merge_function.rb
245
+ - lib/upsert/buffer/sqlite3_database.rb
246
+ - lib/upsert/connection.rb
247
+ - lib/upsert/connection/mysql2_client.rb
248
+ - lib/upsert/connection/pg_connection.rb
249
+ - lib/upsert/connection/sqlite3_database.rb
196
250
  - lib/upsert/row.rb
197
- - lib/upsert/sqlite3_database.rb
198
251
  - lib/upsert/version.rb
199
- - test/helper.rb
200
- - test/misc/get_postgres_reserved_words.rb
201
- - test/misc/mysql_reserved.txt
202
- - test/misc/pg_reserved.txt
203
- - test/shared/binary.rb
204
- - test/shared/correctness.rb
205
- - test/shared/database.rb
206
- - test/shared/multibyte.rb
207
- - test/shared/precision.rb
208
- - test/shared/reserved_words.rb
209
- - test/shared/speed.rb
210
- - test/shared/threaded.rb
211
- - test/shared/timezones.rb
212
- - test/test_active_record_connection_adapter.rb
213
- - test/test_active_record_upsert.rb
214
- - test/test_mysql2.rb
215
- - test/test_pg.rb
216
- - test/test_sqlite.rb
252
+ - spec/active_record_upsert_spec.rb
253
+ - spec/binary_spec.rb
254
+ - spec/correctness_spec.rb
255
+ - spec/database_functions_spec.rb
256
+ - spec/database_spec.rb
257
+ - spec/logger_spec.rb
258
+ - spec/misc/get_postgres_reserved_words.rb
259
+ - spec/misc/mysql_reserved.txt
260
+ - spec/misc/pg_reserved.txt
261
+ - spec/multibyte_spec.rb
262
+ - spec/precision_spec.rb
263
+ - spec/reserved_words_spec.rb
264
+ - spec/spec_helper.rb
265
+ - spec/speed_spec.rb
266
+ - spec/threaded_spec.rb
267
+ - spec/timezones_spec.rb
217
268
  - upsert.gemspec
218
269
  homepage: https://github.com/seamusabshere/upsert
219
270
  licenses: []
@@ -241,22 +292,20 @@ specification_version: 3
241
292
  summary: Upsert for MySQL, PostgreSQL, and SQLite. Finally, all those SQL MERGE tricks
242
293
  codified.
243
294
  test_files:
244
- - test/helper.rb
245
- - test/misc/get_postgres_reserved_words.rb
246
- - test/misc/mysql_reserved.txt
247
- - test/misc/pg_reserved.txt
248
- - test/shared/binary.rb
249
- - test/shared/correctness.rb
250
- - test/shared/database.rb
251
- - test/shared/multibyte.rb
252
- - test/shared/precision.rb
253
- - test/shared/reserved_words.rb
254
- - test/shared/speed.rb
255
- - test/shared/threaded.rb
256
- - test/shared/timezones.rb
257
- - test/test_active_record_connection_adapter.rb
258
- - test/test_active_record_upsert.rb
259
- - test/test_mysql2.rb
260
- - test/test_pg.rb
261
- - test/test_sqlite.rb
295
+ - spec/active_record_upsert_spec.rb
296
+ - spec/binary_spec.rb
297
+ - spec/correctness_spec.rb
298
+ - spec/database_functions_spec.rb
299
+ - spec/database_spec.rb
300
+ - spec/logger_spec.rb
301
+ - spec/misc/get_postgres_reserved_words.rb
302
+ - spec/misc/mysql_reserved.txt
303
+ - spec/misc/pg_reserved.txt
304
+ - spec/multibyte_spec.rb
305
+ - spec/precision_spec.rb
306
+ - spec/reserved_words_spec.rb
307
+ - spec/spec_helper.rb
308
+ - spec/speed_spec.rb
309
+ - spec/threaded_spec.rb
310
+ - spec/timezones_spec.rb
262
311
  has_rdoc: