upsert 2.1.0 → 2.9.10

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.
Files changed (47) hide show
  1. checksums.yaml +5 -5
  2. data/.ruby-version +1 -0
  3. data/.standard.yml +1 -0
  4. data/.travis.yml +60 -12
  5. data/CHANGELOG +39 -0
  6. data/Gemfile +12 -1
  7. data/LICENSE +3 -1
  8. data/README.md +47 -6
  9. data/Rakefile +7 -1
  10. data/lib/upsert.rb +54 -11
  11. data/lib/upsert/column_definition/mysql.rb +2 -2
  12. data/lib/upsert/column_definition/postgresql.rb +9 -8
  13. data/lib/upsert/column_definition/sqlite3.rb +3 -3
  14. data/lib/upsert/connection/Java_ComMysqlJdbc_JDBC4Connection.rb +11 -5
  15. data/lib/upsert/connection/Java_OrgPostgresqlJdbc_PgConnection.rb +33 -0
  16. data/lib/upsert/connection/PG_Connection.rb +10 -1
  17. data/lib/upsert/connection/jdbc.rb +20 -1
  18. data/lib/upsert/connection/postgresql.rb +2 -3
  19. data/lib/upsert/merge_function.rb +5 -4
  20. data/lib/upsert/merge_function/Java_OrgPostgresqlJdbc_PgConnection.rb +27 -0
  21. data/lib/upsert/merge_function/PG_Connection.rb +11 -42
  22. data/lib/upsert/merge_function/postgresql.rb +215 -1
  23. data/lib/upsert/merge_function/sqlite3.rb +10 -0
  24. data/lib/upsert/version.rb +1 -1
  25. data/spec/active_record_upsert_spec.rb +10 -0
  26. data/spec/correctness_spec.rb +34 -5
  27. data/spec/database_functions_spec.rb +16 -9
  28. data/spec/database_spec.rb +7 -0
  29. data/spec/hstore_spec.rb +56 -55
  30. data/spec/jruby_spec.rb +9 -0
  31. data/spec/logger_spec.rb +8 -6
  32. data/spec/postgresql_spec.rb +94 -0
  33. data/spec/reserved_words_spec.rb +21 -17
  34. data/spec/sequel_spec.rb +26 -7
  35. data/spec/spec_helper.rb +251 -92
  36. data/spec/speed_spec.rb +3 -32
  37. data/spec/threaded_spec.rb +35 -12
  38. data/spec/type_safety_spec.rb +2 -1
  39. data/travis/install_postgres.sh +18 -0
  40. data/travis/run_docker_db.sh +20 -0
  41. data/travis/tune_mysql.sh +7 -0
  42. data/upsert-java.gemspec +13 -0
  43. data/upsert.gemspec +9 -57
  44. data/upsert.gemspec.common +107 -0
  45. metadata +53 -40
  46. data/lib/upsert/connection/Java_OrgPostgresqlJdbc4_Jdbc4Connection.rb +0 -15
  47. data/lib/upsert/merge_function/Java_OrgPostgresqlJdbc4_Jdbc4Connection.rb +0 -39
@@ -2,6 +2,16 @@ class Upsert
2
2
  class MergeFunction
3
3
  # @private
4
4
  module Sqlite3
5
+ def self.included(klass)
6
+ klass.extend ClassMethods
7
+ end
8
+
9
+ module ClassMethods
10
+ def clear(*)
11
+ # not necessary
12
+ end
13
+ end
14
+
5
15
  attr_reader :quoted_setter_names
6
16
  attr_reader :quoted_update_names
7
17
  attr_reader :quoted_selector_names
@@ -1,3 +1,3 @@
1
1
  class Upsert
2
- VERSION = '2.1.0'
2
+ VERSION = "2.9.10"
3
3
  end
@@ -11,6 +11,16 @@ describe Upsert do
11
11
  Pet.upsert({:name => 'Jerry'}, :good => true)
12
12
  end
13
13
  end
14
+
15
+ it "doesn't fail inside a transaction" do
16
+ Upsert.clear_database_functions(Pet.connection)
17
+ expect {
18
+ Pet.transaction do
19
+ Pet.upsert({name: 'Simba'}, good: true)
20
+ end
21
+ }.to_not raise_error
22
+ expect(Pet.first.name).to eq('Simba')
23
+ end
14
24
  end
15
25
  end
16
26
  end
@@ -1,3 +1,5 @@
1
+ # encoding: utf-8
2
+
1
3
  require 'spec_helper'
2
4
  describe Upsert do
3
5
  describe 'clever correctness' do
@@ -11,7 +13,8 @@ describe Upsert do
11
13
  u = Upsert.new($conn, :pets)
12
14
  selector = {:name => 'Jerry', :tag_number => 6}
13
15
  u.row(selector)
14
- Pet.find_by_name('Jerry').tag_number.should == 5
16
+ p.reload.tag_number.should == 5
17
+ next
15
18
 
16
19
  # won't change anything because selector is wrong
17
20
  u = Upsert.new($conn, :pets)
@@ -78,6 +81,18 @@ describe Upsert do
78
81
  end
79
82
  end
80
83
 
84
+ it "works with utf-8 data" do
85
+ u = Upsert.new($conn, :pets)
86
+ records = [
87
+ {:name => '你好', :home_address => '人'},
88
+ {:name => 'Здравствуйте', :home_address => 'человек'},
89
+ {:name => '😀', :home_address => '😂'},
90
+ ]
91
+ assert_creates(Pet, records) do
92
+ records.each { |rec| u.row(rec) }
93
+ end
94
+ end
95
+
81
96
  it "tells you if you request a column that doesn't exist" do
82
97
  u = Upsert.new($conn, :pets)
83
98
  lambda { u.row(:gibberish => 'ba') }.should raise_error(/invalid col/i)
@@ -86,6 +101,15 @@ describe Upsert do
86
101
  lambda { u.row(:name => 'Jerry', :gibberish => 'ba', :gender => 'male') }.should raise_error(/invalid col/i)
87
102
  end
88
103
 
104
+ it "works with a long setter hash" do
105
+ Upsert.batch($conn, :alphabets) do |batch|
106
+ 10_000.times do |time|
107
+ setter = Hash[("a".."z").map { |letter| ["the_letter_#{letter}".to_sym, rand(100)] }]
108
+ selector = Hash[("a".."z").map { |letter| ["the_letter_#{letter}".to_sym, rand(100)] }]
109
+ batch.row(setter, selector)
110
+ end
111
+ end
112
+ end
89
113
  end
90
114
 
91
115
  describe "is just as correct as other ways" do
@@ -93,8 +117,8 @@ describe Upsert do
93
117
  it "is as correct as than new/set/save" do
94
118
  assert_same_result lotsa_records do |records|
95
119
  records.each do |selector, setter|
96
- if pet = Pet.where(selector).first
97
- pet.update_attributes setter, :without_protection => true
120
+ if (pet = Pet.where(selector).first)
121
+ pet.update_attributes(setter)
98
122
  else
99
123
  pet = Pet.new
100
124
  selector.each do |k, v|
@@ -134,12 +158,15 @@ describe Upsert do
134
158
  # end
135
159
  end
136
160
 
137
- if ENV['DB'] == 'mysql' && RUBY_VERSION >= '1.9'
161
+ if ENV['DB'] == 'mysql' || (UNIQUE_CONSTRAINT && ENV["DB"] == "postgresql")
138
162
  describe 'compared to activerecord-import' do
139
163
  it "is as correct as faking upserts with activerecord-import" do
140
164
  assert_same_result lotsa_records do |records|
141
165
  columns = nil
142
166
  all_values = []
167
+ # Reverse because we want to mimic an 'overwrite' of previous values
168
+ records = records.reverse.uniq { |s, _| s } if ENV['DB'] == "postgresql"
169
+
143
170
  records.each do |selector, setter|
144
171
  columns ||= (selector.keys + setter.keys).uniq
145
172
  all_values << columns.map do |k|
@@ -151,7 +178,9 @@ describe Upsert do
151
178
  end
152
179
  end
153
180
  end
154
- Pet.import columns, all_values, :timestamps => false, :on_duplicate_key_update => columns
181
+
182
+ conflict_update = ENV['DB'] == "postgresql" ? {conflict_target: records.first.first.keys, columns: columns} : columns
183
+ Pet.import columns, all_values, :timestamps => false, :on_duplicate_key_update => conflict_update
155
184
  end
156
185
  end
157
186
  end
@@ -1,7 +1,15 @@
1
1
  require 'spec_helper'
2
2
  require 'stringio'
3
+ require 'upsert/merge_function/postgresql'
4
+
3
5
  describe Upsert do
4
6
  describe 'database functions' do
7
+ version = 'postgresql' == ENV['DB'] ? Upsert::MergeFunction::Postgresql.extract_version(
8
+ Pet.connection.select_value("SHOW server_version")
9
+ ) : 0
10
+ before(:each) {
11
+ skip "Not using DB functions" if 'postgresql' == ENV['DB'] && UNIQUE_CONSTRAINT && version >= 90500
12
+ }
5
13
  it "does not re-use merge functions across connections" do
6
14
  begin
7
15
  io = StringIO.new
@@ -15,7 +23,7 @@ describe Upsert do
15
23
  # clear, create (#2)
16
24
  Upsert.clear_database_functions($conn_factory.new_connection)
17
25
  Upsert.new($conn_factory.new_connection, :pets).row :name => 'hello'
18
-
26
+
19
27
  io.rewind
20
28
  hits = io.read.split("\n").grep(/Creating or replacing/)
21
29
  hits.length.should == 2
@@ -23,13 +31,13 @@ describe Upsert do
23
31
  Upsert.logger = old_logger
24
32
  end
25
33
  end
26
-
34
+
27
35
  it "does not re-use merge functions even when on the same connection" do
28
36
  begin
29
37
  io = StringIO.new
30
38
  old_logger = Upsert.logger
31
39
  Upsert.logger = Logger.new io, Logger::INFO
32
-
40
+
33
41
  connection = $conn_factory.new_connection
34
42
 
35
43
  # clear, create (#1)
@@ -39,7 +47,7 @@ describe Upsert do
39
47
  # clear, create (#2)
40
48
  Upsert.clear_database_functions(connection)
41
49
  Upsert.new(connection, :pets).row :name => 'hello'
42
-
50
+
43
51
  io.rewind
44
52
  hits = io.read.split("\n").grep(/Creating or replacing/)
45
53
  hits.length.should == 2
@@ -47,7 +55,7 @@ describe Upsert do
47
55
  Upsert.logger = old_logger
48
56
  end
49
57
  end
50
-
58
+
51
59
  it "re-uses merge functions within batch" do
52
60
  begin
53
61
  io = StringIO.new
@@ -56,13 +64,13 @@ describe Upsert do
56
64
 
57
65
  # clear
58
66
  Upsert.clear_database_functions($conn_factory.new_connection)
59
-
67
+
60
68
  # create
61
69
  Upsert.batch($conn_factory.new_connection, :pets) do |upsert|
62
70
  upsert.row :name => 'hello'
63
71
  upsert.row :name => 'world'
64
72
  end
65
-
73
+
66
74
  io.rewind
67
75
  hits = io.read.split("\n").grep(/Creating or replacing/)
68
76
  hits.length.should == 1
@@ -79,7 +87,7 @@ describe Upsert do
79
87
 
80
88
  # clear
81
89
  Upsert.clear_database_functions($conn_factory.new_connection)
82
-
90
+
83
91
  # tries, "went missing", creates
84
92
  Upsert.new($conn_factory.new_connection, :pets, :assume_function_exists => true).row :name => 'hello'
85
93
 
@@ -94,6 +102,5 @@ describe Upsert do
94
102
  Upsert.logger = old_logger
95
103
  end
96
104
  end
97
-
98
105
  end
99
106
  end if %w{ postgresql mysql }.include?(ENV['DB'])
@@ -83,6 +83,13 @@ describe Upsert do
83
83
  upsert.row({:id => jerry.id}, :gender => :male)
84
84
  end
85
85
  end
86
+
87
+ it "works for column names with spaces in them" do
88
+ upsert = Upsert.new $conn, :people
89
+ assert_creates(Person, [{:"First Name" => 'Major', :"Last Name" => 'Major'}]) do
90
+ upsert.row({:"First Name" => 'Major'}, :"Last Name" => 'Major')
91
+ end
92
+ end
86
93
  end
87
94
  describe :batch do
88
95
  it "works for multiple rows (base case)" do
data/spec/hstore_spec.rb CHANGED
@@ -3,7 +3,22 @@ require 'spec_helper'
3
3
  describe Upsert do
4
4
  describe 'hstore on pg' do
5
5
  require 'pg_hstore'
6
- Pet.connection.execute 'CREATE EXTENSION HSTORE'
6
+
7
+ let(:deserializer) do
8
+ klass = PgHstore.dup
9
+ if RUBY_PLATFORM == "java"
10
+ # activerecord-jdbc-adapter has native support for hstore
11
+ klass.class_eval do
12
+ def self.parse(obj)
13
+ obj
14
+ end
15
+ end
16
+ end
17
+
18
+ klass
19
+ end
20
+
21
+ Pet.connection.execute 'CREATE EXTENSION IF NOT EXISTS HSTORE'
7
22
  Pet.connection.execute "ALTER TABLE pets ADD COLUMN crazy HSTORE"
8
23
  Pet.connection.execute "ALTER TABLE pets ADD COLUMN cool HSTORE"
9
24
 
@@ -11,27 +26,26 @@ describe Upsert do
11
26
  Pet.delete_all
12
27
  end
13
28
 
29
+ let(:upsert) { Upsert.new $conn, :pets }
30
+
14
31
  it "works for ugly text" do
15
- upsert = Upsert.new $conn, :pets
16
32
  uggy = <<-EOS
17
33
  {"results":[{"locations":[],"providedLocation":{"location":"3001 STRATTON WAY, MADISON, WI 53719 UNITED STATES"}}],"options":{"ignoreLatLngInput":true,"maxResults":1,"thumbMaps":false},"info":{"copyright":{"text":"© 2012 MapQuest, Inc.","imageUrl":"http://api.mqcdn.com/res/mqlogo.gif","imageAltText":"© 2012 MapQuest, Inc."},"statuscode":0,"messages":[]}}
18
34
  EOS
19
35
  upsert.row({:name => 'Uggy'}, :crazy => {:uggy => uggy})
20
36
  row = Pet.connection.select_one(%{SELECT crazy FROM pets WHERE name = 'Uggy'})
21
- crazy = PgHstore.parse row['crazy']
37
+ crazy = deserializer.parse row['crazy']
22
38
  crazy.should == { 'uggy' => uggy }
23
39
  end
24
40
 
25
41
  it "just works" do
26
- upsert = Upsert.new $conn, :pets
27
-
28
42
  upsert.row({:name => 'Bill'}, :crazy => nil)
29
43
  row = Pet.connection.select_one(%{SELECT crazy FROM pets WHERE name = 'Bill'})
30
44
  row['crazy'].should == nil
31
45
 
32
46
  upsert.row({:name => 'Bill'}, :crazy => {:a => 1})
33
47
  row = Pet.connection.select_one(%{SELECT crazy FROM pets WHERE name = 'Bill'})
34
- crazy = PgHstore.parse row['crazy']
48
+ crazy = deserializer.parse row['crazy']
35
49
  crazy.should == { 'a' => '1' }
36
50
 
37
51
  upsert.row({:name => 'Bill'}, :crazy => nil)
@@ -40,31 +54,29 @@ EOS
40
54
 
41
55
  upsert.row({:name => 'Bill'}, :crazy => {:a => 1})
42
56
  row = Pet.connection.select_one(%{SELECT crazy FROM pets WHERE name = 'Bill'})
43
- crazy = PgHstore.parse row['crazy']
57
+ crazy = deserializer.parse row['crazy']
44
58
  crazy.should == { 'a' => '1' }
45
59
 
46
60
  upsert.row({:name => 'Bill'}, :crazy => {:whatdat => 'whodat'})
47
61
  row = Pet.connection.select_one(%{SELECT crazy FROM pets WHERE name = 'Bill'})
48
- crazy = PgHstore.parse row['crazy']
62
+ crazy = deserializer.parse row['crazy']
49
63
  crazy.should == { 'a' => '1', 'whatdat' => 'whodat' }
50
64
 
51
65
  upsert.row({:name => 'Bill'}, :crazy => {:whatdat => "D'ONOFRIO"})
52
66
  row = Pet.connection.select_one(%{SELECT crazy FROM pets WHERE name = 'Bill'})
53
- crazy = PgHstore.parse row['crazy']
67
+ crazy = deserializer.parse row['crazy']
54
68
  crazy.should == { 'a' => '1', 'whatdat' => "D'ONOFRIO" }
55
69
 
56
70
  upsert.row({:name => 'Bill'}, :crazy => {:a => 2})
57
71
  row = Pet.connection.select_one(%{SELECT crazy FROM pets WHERE name = 'Bill'})
58
- crazy = PgHstore.parse row['crazy']
72
+ crazy = deserializer.parse row['crazy']
59
73
  crazy.should == { 'a' => '2', 'whatdat' => "D'ONOFRIO" }
60
74
  end
61
75
 
62
76
  it "can nullify entire hstore" do
63
- upsert = Upsert.new $conn, :pets
64
-
65
77
  upsert.row({:name => 'Bill'}, :crazy => {:a => 1})
66
78
  row = Pet.connection.select_one(%{SELECT crazy FROM pets WHERE name = 'Bill'})
67
- crazy = PgHstore.parse row['crazy']
79
+ crazy = deserializer.parse row['crazy']
68
80
  crazy.should == { 'a' => '1' }
69
81
 
70
82
  upsert.row({:name => 'Bill'}, :crazy => nil)
@@ -73,174 +85,163 @@ EOS
73
85
  end
74
86
 
75
87
  it "deletes keys that are nil" do
76
- upsert = Upsert.new $conn, :pets
77
-
78
88
  upsert.row({:name => 'Bill'}, :crazy => nil)
79
89
  row = Pet.connection.select_one(%{SELECT crazy FROM pets WHERE name = 'Bill'})
80
90
  row['crazy'].should == nil
81
91
 
82
92
  upsert.row({:name => 'Bill'}, :crazy => {:a => 1})
83
93
  row = Pet.connection.select_one(%{SELECT crazy FROM pets WHERE name = 'Bill'})
84
- crazy = PgHstore.parse row['crazy']
94
+ crazy = deserializer.parse row['crazy']
85
95
  crazy.should == { 'a' => '1' }
86
96
 
87
97
  upsert.row({:name => 'Bill'}, :crazy => {})
88
98
  row = Pet.connection.select_one(%{SELECT crazy FROM pets WHERE name = 'Bill'})
89
- crazy = PgHstore.parse row['crazy']
99
+ crazy = deserializer.parse row['crazy']
90
100
  crazy.should == { 'a' => '1' }
91
101
 
92
102
  upsert.row({:name => 'Bill'}, :crazy => {:a => nil})
93
103
  row = Pet.connection.select_one(%{SELECT crazy FROM pets WHERE name = 'Bill'})
94
- crazy = PgHstore.parse row['crazy']
104
+ crazy = deserializer.parse row['crazy']
95
105
  crazy.should == {}
96
106
 
97
107
  upsert.row({:name => 'Bill'}, :crazy => {:a => 1, :b => 5})
98
108
  row = Pet.connection.select_one(%{SELECT crazy FROM pets WHERE name = 'Bill'})
99
- crazy = PgHstore.parse row['crazy']
109
+ crazy = deserializer.parse row['crazy']
100
110
  crazy.should == { 'a' => '1', 'b' => '5' }
101
111
 
102
112
  upsert.row({:name => 'Bill'}, :crazy => {})
103
113
  row = Pet.connection.select_one(%{SELECT crazy FROM pets WHERE name = 'Bill'})
104
- crazy = PgHstore.parse row['crazy']
114
+ crazy = deserializer.parse row['crazy']
105
115
  crazy.should == { 'a' => '1', 'b' => '5' }
106
116
 
107
117
  upsert.row({:name => 'Bill'}, :crazy => {:a => nil})
108
118
  row = Pet.connection.select_one(%{SELECT crazy FROM pets WHERE name = 'Bill'})
109
- crazy = PgHstore.parse row['crazy']
119
+ crazy = deserializer.parse row['crazy']
110
120
  crazy.should == { 'b' => '5' }
111
121
 
112
122
  upsert.row({:name => 'Bill'}, :crazy => {:a => 1, :b => 5})
113
123
  row = Pet.connection.select_one(%{SELECT crazy FROM pets WHERE name = 'Bill'})
114
- crazy = PgHstore.parse row['crazy']
124
+ crazy = deserializer.parse row['crazy']
115
125
  crazy.should == { 'a' => '1', 'b' => '5' }
116
126
 
117
127
  upsert.row({:name => 'Bill'}, :crazy => {:a => nil, :b => nil, :c => 12})
118
128
  row = Pet.connection.select_one(%{SELECT crazy FROM pets WHERE name = 'Bill'})
119
- crazy = PgHstore.parse row['crazy']
129
+ crazy = deserializer.parse row['crazy']
120
130
  crazy.should == { 'c' => '12' }
121
131
  end
122
132
 
123
133
  it "takes dangerous keys" do
124
- upsert = Upsert.new $conn, :pets
125
-
126
134
  upsert.row({:name => 'Bill'}, :crazy => nil)
127
135
  row = Pet.connection.select_one(%{SELECT crazy FROM pets WHERE name = 'Bill'})
128
136
  row['crazy'].should == nil
129
137
 
130
138
  upsert.row({:name => 'Bill'}, :crazy => {:'foo"bar' => 1})
131
139
  row = Pet.connection.select_one(%{SELECT crazy FROM pets WHERE name = 'Bill'})
132
- crazy = PgHstore.parse row['crazy']
140
+ crazy = deserializer.parse row['crazy']
133
141
  crazy.should == { 'foo"bar' => '1' }
134
142
 
135
143
  upsert.row({:name => 'Bill'}, :crazy => {})
136
144
  row = Pet.connection.select_one(%{SELECT crazy FROM pets WHERE name = 'Bill'})
137
- crazy = PgHstore.parse row['crazy']
145
+ crazy = deserializer.parse row['crazy']
138
146
  crazy.should == { 'foo"bar' => '1' }
139
147
 
140
148
  upsert.row({:name => 'Bill'}, :crazy => {:'foo"bar' => nil})
141
149
  row = Pet.connection.select_one(%{SELECT crazy FROM pets WHERE name = 'Bill'})
142
- crazy = PgHstore.parse row['crazy']
150
+ crazy = deserializer.parse row['crazy']
143
151
  crazy.should == {}
144
152
 
145
153
  upsert.row({:name => 'Bill'}, :crazy => {:'foo"bar' => 1, :b => 5})
146
154
  row = Pet.connection.select_one(%{SELECT crazy FROM pets WHERE name = 'Bill'})
147
- crazy = PgHstore.parse row['crazy']
155
+ crazy = deserializer.parse row['crazy']
148
156
  crazy.should == { 'foo"bar' => '1', 'b' => '5' }
149
157
 
150
158
  upsert.row({:name => 'Bill'}, :crazy => {})
151
159
  row = Pet.connection.select_one(%{SELECT crazy FROM pets WHERE name = 'Bill'})
152
- crazy = PgHstore.parse row['crazy']
160
+ crazy = deserializer.parse row['crazy']
153
161
  crazy.should == { 'foo"bar' => '1', 'b' => '5' }
154
162
 
155
163
  upsert.row({:name => 'Bill'}, :crazy => {:'foo"bar' => nil})
156
164
  row = Pet.connection.select_one(%{SELECT crazy FROM pets WHERE name = 'Bill'})
157
- crazy = PgHstore.parse row['crazy']
165
+ crazy = deserializer.parse row['crazy']
158
166
  crazy.should == { 'b' => '5' }
159
167
 
160
168
  upsert.row({:name => 'Bill'}, :crazy => {:'foo"bar' => 1, :b => 5})
161
169
  row = Pet.connection.select_one(%{SELECT crazy FROM pets WHERE name = 'Bill'})
162
- crazy = PgHstore.parse row['crazy']
170
+ crazy = deserializer.parse row['crazy']
163
171
  crazy.should == { 'foo"bar' => '1', 'b' => '5' }
164
172
 
165
173
  upsert.row({:name => 'Bill'}, :crazy => {:'foo"bar' => nil, :b => nil, :c => 12})
166
174
  row = Pet.connection.select_one(%{SELECT crazy FROM pets WHERE name = 'Bill'})
167
- crazy = PgHstore.parse row['crazy']
175
+ crazy = deserializer.parse row['crazy']
168
176
  crazy.should == { 'c' => '12' }
169
177
  end
170
178
 
171
179
  it "handles multiple hstores" do
172
- upsert = Upsert.new $conn, :pets
173
180
  upsert.row({:name => 'Bill'}, :crazy => {:a => 1, :b => 9}, :cool => {:c => 12, :d => 19})
174
181
  row = Pet.connection.select_one(%{SELECT crazy, cool FROM pets WHERE name = 'Bill'})
175
- crazy = PgHstore.parse row['crazy']
182
+ crazy = deserializer.parse row['crazy']
176
183
  crazy.should == { 'a' => '1', 'b' => '9' }
177
- cool = PgHstore.parse row['cool']
184
+ cool = deserializer.parse row['cool']
178
185
  cool.should == { 'c' => '12', 'd' => '19' }
179
186
  end
180
187
 
181
188
  it "can deletes keys from multiple hstores at once" do
182
- upsert = Upsert.new $conn, :pets
183
-
184
189
  upsert.row({:name => 'Bill'}, :crazy => {:a => 1}, :cool => {5 => 9})
185
190
  row = Pet.connection.select_one(%{SELECT crazy, cool FROM pets WHERE name = 'Bill'})
186
- crazy = PgHstore.parse row['crazy']
191
+ crazy = deserializer.parse row['crazy']
187
192
  crazy.should == { 'a' => '1' }
188
- cool = PgHstore.parse row['cool']
193
+ cool = deserializer.parse row['cool']
189
194
  cool.should == { '5' => '9' }
190
195
 
191
196
  # NOOP
192
197
  upsert.row({:name => 'Bill'}, :crazy => {}, :cool => {})
193
198
  row = Pet.connection.select_one(%{SELECT crazy, cool FROM pets WHERE name = 'Bill'})
194
- crazy = PgHstore.parse row['crazy']
199
+ crazy = deserializer.parse row['crazy']
195
200
  crazy.should == { 'a' => '1' }
196
- cool = PgHstore.parse row['cool']
201
+ cool = deserializer.parse row['cool']
197
202
  cool.should == { '5' => '9' }
198
203
 
199
204
  upsert.row({:name => 'Bill'}, :crazy => {:a => nil}, :cool => {13 => 17})
200
205
  row = Pet.connection.select_one(%{SELECT crazy, cool FROM pets WHERE name = 'Bill'})
201
- crazy = PgHstore.parse row['crazy']
206
+ crazy = deserializer.parse row['crazy']
202
207
  crazy.should == {}
203
- cool = PgHstore.parse row['cool']
208
+ cool = deserializer.parse row['cool']
204
209
  cool.should == { '5' => '9', '13' => '17' }
205
210
 
206
211
  upsert.row({:name => 'Bill'}, :crazy => {:a => 1, :b => 5})
207
212
  row = Pet.connection.select_one(%{SELECT crazy, cool FROM pets WHERE name = 'Bill'})
208
- crazy = PgHstore.parse row['crazy']
213
+ crazy = deserializer.parse row['crazy']
209
214
  crazy.should == { 'a' => '1', 'b' => '5' }
210
215
 
211
216
  upsert.row({:name => 'Bill'}, :crazy => {:b => nil}, :cool => {5 => nil})
212
217
  row = Pet.connection.select_one(%{SELECT crazy, cool FROM pets WHERE name = 'Bill'})
213
- crazy = PgHstore.parse row['crazy']
218
+ crazy = deserializer.parse row['crazy']
214
219
  crazy.should == {'a' => '1'}
215
- cool = PgHstore.parse row['cool']
220
+ cool = deserializer.parse row['cool']
216
221
  cool.should == {'13' => '17' }
217
222
  end
218
223
 
219
224
  it "deletes keys whether new or existing record" do
220
- upsert = Upsert.new $conn, :pets
221
-
222
225
  upsert.row({:name => 'Bill'}, :crazy => {:z => 1, :x => nil})
223
226
  row = Pet.connection.select_one(%{SELECT crazy FROM pets WHERE name = 'Bill'})
224
- crazy = PgHstore.parse row['crazy']
227
+ crazy = deserializer.parse row['crazy']
225
228
  crazy.should == { 'z' => '1' }
226
229
 
227
230
  upsert.row({:name => 'Bill'}, :crazy => {:a => 1})
228
231
  row = Pet.connection.select_one(%{SELECT crazy FROM pets WHERE name = 'Bill'})
229
- crazy = PgHstore.parse row['crazy']
232
+ crazy = deserializer.parse row['crazy']
230
233
  crazy.should == { 'a' => '1', 'z' => '1' }
231
234
  end
232
235
 
233
236
  it "can turn off eager nullify" do
234
- upsert = Upsert.new $conn, :pets
235
-
236
237
  upsert.row({:name => 'Bill'}, {:crazy => {:z => 1, :x => nil}}, :eager_nullify => false)
237
238
  row = Pet.connection.select_one(%{SELECT crazy FROM pets WHERE name = 'Bill'})
238
- crazy = PgHstore.parse row['crazy']
239
+ crazy = deserializer.parse row['crazy']
239
240
  crazy.should == { 'z' => '1', 'x' => nil }
240
241
 
241
242
  upsert.row({:name => 'Bill'}, :crazy => {:a => 1})
242
243
  row = Pet.connection.select_one(%{SELECT crazy FROM pets WHERE name = 'Bill'})
243
- crazy = PgHstore.parse row['crazy']
244
+ crazy = deserializer.parse row['crazy']
244
245
  crazy.should == { 'a' => '1', 'z' => '1', 'x' => nil}
245
246
  end
246
247