upsert 2.9.10-java

Sign up to get free protection for your applications and to get access to all the features.
Files changed (68) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +19 -0
  3. data/.ruby-version +1 -0
  4. data/.standard.yml +1 -0
  5. data/.travis.yml +63 -0
  6. data/.yardopts +2 -0
  7. data/CHANGELOG +265 -0
  8. data/Gemfile +20 -0
  9. data/LICENSE +24 -0
  10. data/README.md +411 -0
  11. data/Rakefile +54 -0
  12. data/lib/upsert.rb +284 -0
  13. data/lib/upsert/active_record_upsert.rb +12 -0
  14. data/lib/upsert/binary.rb +8 -0
  15. data/lib/upsert/column_definition.rb +79 -0
  16. data/lib/upsert/column_definition/mysql.rb +24 -0
  17. data/lib/upsert/column_definition/postgresql.rb +66 -0
  18. data/lib/upsert/column_definition/sqlite3.rb +34 -0
  19. data/lib/upsert/connection.rb +37 -0
  20. data/lib/upsert/connection/Java_ComMysqlJdbc_JDBC4Connection.rb +31 -0
  21. data/lib/upsert/connection/Java_OrgPostgresqlJdbc_PgConnection.rb +33 -0
  22. data/lib/upsert/connection/Java_OrgSqlite_Conn.rb +17 -0
  23. data/lib/upsert/connection/Mysql2_Client.rb +76 -0
  24. data/lib/upsert/connection/PG_Connection.rb +35 -0
  25. data/lib/upsert/connection/SQLite3_Database.rb +28 -0
  26. data/lib/upsert/connection/jdbc.rb +105 -0
  27. data/lib/upsert/connection/postgresql.rb +24 -0
  28. data/lib/upsert/connection/sqlite3.rb +19 -0
  29. data/lib/upsert/merge_function.rb +73 -0
  30. data/lib/upsert/merge_function/Java_ComMysqlJdbc_JDBC4Connection.rb +42 -0
  31. data/lib/upsert/merge_function/Java_OrgPostgresqlJdbc_PgConnection.rb +27 -0
  32. data/lib/upsert/merge_function/Java_OrgSqlite_Conn.rb +10 -0
  33. data/lib/upsert/merge_function/Mysql2_Client.rb +36 -0
  34. data/lib/upsert/merge_function/PG_Connection.rb +26 -0
  35. data/lib/upsert/merge_function/SQLite3_Database.rb +10 -0
  36. data/lib/upsert/merge_function/mysql.rb +66 -0
  37. data/lib/upsert/merge_function/postgresql.rb +365 -0
  38. data/lib/upsert/merge_function/sqlite3.rb +43 -0
  39. data/lib/upsert/row.rb +59 -0
  40. data/lib/upsert/version.rb +3 -0
  41. data/spec/active_record_upsert_spec.rb +26 -0
  42. data/spec/binary_spec.rb +21 -0
  43. data/spec/correctness_spec.rb +190 -0
  44. data/spec/database_functions_spec.rb +106 -0
  45. data/spec/database_spec.rb +121 -0
  46. data/spec/hstore_spec.rb +249 -0
  47. data/spec/jruby_spec.rb +9 -0
  48. data/spec/logger_spec.rb +52 -0
  49. data/spec/misc/get_postgres_reserved_words.rb +12 -0
  50. data/spec/misc/mysql_reserved.txt +226 -0
  51. data/spec/misc/pg_reserved.txt +742 -0
  52. data/spec/multibyte_spec.rb +27 -0
  53. data/spec/postgresql_spec.rb +94 -0
  54. data/spec/precision_spec.rb +11 -0
  55. data/spec/reserved_words_spec.rb +50 -0
  56. data/spec/sequel_spec.rb +57 -0
  57. data/spec/spec_helper.rb +417 -0
  58. data/spec/speed_spec.rb +44 -0
  59. data/spec/threaded_spec.rb +57 -0
  60. data/spec/timezones_spec.rb +58 -0
  61. data/spec/type_safety_spec.rb +12 -0
  62. data/travis/install_postgres.sh +18 -0
  63. data/travis/run_docker_db.sh +20 -0
  64. data/travis/tune_mysql.sh +7 -0
  65. data/upsert-java.gemspec +14 -0
  66. data/upsert.gemspec +13 -0
  67. data/upsert.gemspec.common +106 -0
  68. metadata +373 -0
@@ -0,0 +1,121 @@
1
+ require 'spec_helper'
2
+ describe Upsert do
3
+ describe "is a database with an upsert trick" do
4
+ describe :row do
5
+ it "works for a single row (base case)" do
6
+ upsert = Upsert.new $conn, :pets
7
+ assert_creates(Pet, [{:name => 'Jerry', :gender => 'male'}]) do
8
+ upsert.row({:name => 'Jerry'}, {:gender => 'male'})
9
+ end
10
+ end
11
+ it "works for complex selectors" do
12
+ upsert = Upsert.new $conn, :pets
13
+ assert_creates(Pet, [{:name => 'Jerry', :gender => 'male', :tag_number => 4}]) do
14
+ upsert.row({:name => 'Jerry', :gender => 'male'}, {:tag_number => 1})
15
+ upsert.row({:name => 'Jerry', :gender => 'male'}, {:tag_number => 4})
16
+ end
17
+ end
18
+ it "doesn't nullify columns that are not included in the selector or setter" do
19
+ assert_creates(Pet, [{:name => 'Jerry', :gender => 'male', :tag_number => 4}]) do
20
+ one = Upsert.new $conn, :pets
21
+ one.row({:name => 'Jerry'}, {:gender => 'male'})
22
+ two = Upsert.new $conn, :pets
23
+ two.row({:name => 'Jerry'}, {:tag_number => 4})
24
+ end
25
+ end
26
+ it "works for a single row (not changing anything)" do
27
+ upsert = Upsert.new $conn, :pets
28
+ assert_creates(Pet, [{:name => 'Jerry', :gender => 'male'}]) do
29
+ upsert.row({:name => 'Jerry'}, {:gender => 'male'})
30
+ upsert.row({:name => 'Jerry'}, {:gender => 'male'})
31
+ end
32
+ end
33
+ it "works for a single row (changing something)" do
34
+ upsert = Upsert.new $conn, :pets
35
+ assert_creates(Pet, [{:name => 'Jerry', :gender => 'neutered'}]) do
36
+ upsert.row({:name => 'Jerry'}, {:gender => 'male'})
37
+ upsert.row({:name => 'Jerry'}, {:gender => 'neutered'})
38
+ end
39
+ Pet.where(:gender => 'male').count.should == 0
40
+ end
41
+ it "works for a single row with implicit nulls" do
42
+ upsert = Upsert.new $conn, :pets
43
+ assert_creates(Pet, [{:name => 'Inky', :gender => nil}]) do
44
+ upsert.row({:name => 'Inky'}, {})
45
+ upsert.row({:name => 'Inky'}, {})
46
+ end
47
+ end
48
+ it "works for a single row with empty setter" do
49
+ upsert = Upsert.new $conn, :pets
50
+ assert_creates(Pet, [{:name => 'Inky', :gender => nil}]) do
51
+ upsert.row(:name => 'Inky')
52
+ upsert.row(:name => 'Inky')
53
+ end
54
+ end
55
+ it "works for a single row with explicit nulls" do
56
+ upsert = Upsert.new $conn, :pets
57
+ assert_creates(Pet, [{:name => 'Inky', :gender => nil}]) do
58
+ upsert.row({:name => 'Inky'}, {:gender => nil})
59
+ upsert.row({:name => 'Inky'}, {:gender => nil})
60
+ end
61
+ end
62
+ it "works with ids" do
63
+ jerry = Pet.create :name => 'Jerry', :lovability => 1.0
64
+ upsert = Upsert.new $conn, :pets
65
+ assert_creates(Pet, [{:name => 'Jerry', :lovability => 2.0}]) do
66
+ upsert.row({:id => jerry.id}, :lovability => 2.0)
67
+ end
68
+ end
69
+ it "does not set the created_at and created_on columns on update" do
70
+ task = Task.create :name => 'Clean bathroom'
71
+ created = task.created_at
72
+ upsert = Upsert.new $conn, :tasks
73
+ upsert.row({:id => task.id}, :name => 'Clean kitchen')
74
+ task.reload
75
+ task.created_at.should eql task.created_at
76
+ task.created_on.should eql task.created_on
77
+ end
78
+
79
+ it "converts symbol values to string" do
80
+ jerry = Pet.create :name => 'Jerry', :gender => 'female'
81
+ upsert = Upsert.new $conn, :pets
82
+ assert_creates(Pet, [{:name => 'Jerry', :gender => 'male'}]) do
83
+ upsert.row({:id => jerry.id}, :gender => :male)
84
+ end
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
93
+ end
94
+ describe :batch do
95
+ it "works for multiple rows (base case)" do
96
+ assert_creates(Pet, [{:name => 'Jerry', :gender => 'male'}]) do
97
+ Upsert.batch($conn, :pets) do |upsert|
98
+ upsert.row({:name => 'Jerry'}, :gender => 'male')
99
+ end
100
+ end
101
+ end
102
+ it "works for multiple rows (not changing anything)" do
103
+ assert_creates(Pet, [{:name => 'Jerry', :gender => 'male'}]) do
104
+ Upsert.batch($conn, :pets) do |upsert|
105
+ upsert.row({:name => 'Jerry'}, :gender => 'male')
106
+ upsert.row({:name => 'Jerry'}, :gender => 'male')
107
+ end
108
+ end
109
+ end
110
+ it "works for multiple rows (changing something)" do
111
+ assert_creates(Pet, [{:name => 'Jerry', :gender => 'neutered'}]) do
112
+ Upsert.batch($conn, :pets) do |upsert|
113
+ upsert.row({:name => 'Jerry'}, :gender => 'male')
114
+ upsert.row({:name => 'Jerry'}, :gender => 'neutered')
115
+ end
116
+ end
117
+ Pet.where(:gender => 'male').count.should == 0
118
+ end
119
+ end
120
+ end
121
+ end
@@ -0,0 +1,249 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require 'spec_helper'
3
+ describe Upsert do
4
+ describe 'hstore on pg' do
5
+ require 'pg_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'
22
+ Pet.connection.execute "ALTER TABLE pets ADD COLUMN crazy HSTORE"
23
+ Pet.connection.execute "ALTER TABLE pets ADD COLUMN cool HSTORE"
24
+
25
+ before do
26
+ Pet.delete_all
27
+ end
28
+
29
+ let(:upsert) { Upsert.new $conn, :pets }
30
+
31
+ it "works for ugly text" do
32
+ uggy = <<-EOS
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":[]}}
34
+ EOS
35
+ upsert.row({:name => 'Uggy'}, :crazy => {:uggy => uggy})
36
+ row = Pet.connection.select_one(%{SELECT crazy FROM pets WHERE name = 'Uggy'})
37
+ crazy = deserializer.parse row['crazy']
38
+ crazy.should == { 'uggy' => uggy }
39
+ end
40
+
41
+ it "just works" do
42
+ upsert.row({:name => 'Bill'}, :crazy => nil)
43
+ row = Pet.connection.select_one(%{SELECT crazy FROM pets WHERE name = 'Bill'})
44
+ row['crazy'].should == nil
45
+
46
+ upsert.row({:name => 'Bill'}, :crazy => {:a => 1})
47
+ row = Pet.connection.select_one(%{SELECT crazy FROM pets WHERE name = 'Bill'})
48
+ crazy = deserializer.parse row['crazy']
49
+ crazy.should == { 'a' => '1' }
50
+
51
+ upsert.row({:name => 'Bill'}, :crazy => nil)
52
+ row = Pet.connection.select_one(%{SELECT crazy FROM pets WHERE name = 'Bill'})
53
+ row['crazy'].should == nil
54
+
55
+ upsert.row({:name => 'Bill'}, :crazy => {:a => 1})
56
+ row = Pet.connection.select_one(%{SELECT crazy FROM pets WHERE name = 'Bill'})
57
+ crazy = deserializer.parse row['crazy']
58
+ crazy.should == { 'a' => '1' }
59
+
60
+ upsert.row({:name => 'Bill'}, :crazy => {:whatdat => 'whodat'})
61
+ row = Pet.connection.select_one(%{SELECT crazy FROM pets WHERE name = 'Bill'})
62
+ crazy = deserializer.parse row['crazy']
63
+ crazy.should == { 'a' => '1', 'whatdat' => 'whodat' }
64
+
65
+ upsert.row({:name => 'Bill'}, :crazy => {:whatdat => "D'ONOFRIO"})
66
+ row = Pet.connection.select_one(%{SELECT crazy FROM pets WHERE name = 'Bill'})
67
+ crazy = deserializer.parse row['crazy']
68
+ crazy.should == { 'a' => '1', 'whatdat' => "D'ONOFRIO" }
69
+
70
+ upsert.row({:name => 'Bill'}, :crazy => {:a => 2})
71
+ row = Pet.connection.select_one(%{SELECT crazy FROM pets WHERE name = 'Bill'})
72
+ crazy = deserializer.parse row['crazy']
73
+ crazy.should == { 'a' => '2', 'whatdat' => "D'ONOFRIO" }
74
+ end
75
+
76
+ it "can nullify entire hstore" do
77
+ upsert.row({:name => 'Bill'}, :crazy => {:a => 1})
78
+ row = Pet.connection.select_one(%{SELECT crazy FROM pets WHERE name = 'Bill'})
79
+ crazy = deserializer.parse row['crazy']
80
+ crazy.should == { 'a' => '1' }
81
+
82
+ upsert.row({:name => 'Bill'}, :crazy => nil)
83
+ row = Pet.connection.select_one(%{SELECT crazy FROM pets WHERE name = 'Bill'})
84
+ row['crazy'].should == nil
85
+ end
86
+
87
+ it "deletes keys that are nil" do
88
+ upsert.row({:name => 'Bill'}, :crazy => nil)
89
+ row = Pet.connection.select_one(%{SELECT crazy FROM pets WHERE name = 'Bill'})
90
+ row['crazy'].should == nil
91
+
92
+ upsert.row({:name => 'Bill'}, :crazy => {:a => 1})
93
+ row = Pet.connection.select_one(%{SELECT crazy FROM pets WHERE name = 'Bill'})
94
+ crazy = deserializer.parse row['crazy']
95
+ crazy.should == { 'a' => '1' }
96
+
97
+ upsert.row({:name => 'Bill'}, :crazy => {})
98
+ row = Pet.connection.select_one(%{SELECT crazy FROM pets WHERE name = 'Bill'})
99
+ crazy = deserializer.parse row['crazy']
100
+ crazy.should == { 'a' => '1' }
101
+
102
+ upsert.row({:name => 'Bill'}, :crazy => {:a => nil})
103
+ row = Pet.connection.select_one(%{SELECT crazy FROM pets WHERE name = 'Bill'})
104
+ crazy = deserializer.parse row['crazy']
105
+ crazy.should == {}
106
+
107
+ upsert.row({:name => 'Bill'}, :crazy => {:a => 1, :b => 5})
108
+ row = Pet.connection.select_one(%{SELECT crazy FROM pets WHERE name = 'Bill'})
109
+ crazy = deserializer.parse row['crazy']
110
+ crazy.should == { 'a' => '1', 'b' => '5' }
111
+
112
+ upsert.row({:name => 'Bill'}, :crazy => {})
113
+ row = Pet.connection.select_one(%{SELECT crazy FROM pets WHERE name = 'Bill'})
114
+ crazy = deserializer.parse row['crazy']
115
+ crazy.should == { 'a' => '1', 'b' => '5' }
116
+
117
+ upsert.row({:name => 'Bill'}, :crazy => {:a => nil})
118
+ row = Pet.connection.select_one(%{SELECT crazy FROM pets WHERE name = 'Bill'})
119
+ crazy = deserializer.parse row['crazy']
120
+ crazy.should == { 'b' => '5' }
121
+
122
+ upsert.row({:name => 'Bill'}, :crazy => {:a => 1, :b => 5})
123
+ row = Pet.connection.select_one(%{SELECT crazy FROM pets WHERE name = 'Bill'})
124
+ crazy = deserializer.parse row['crazy']
125
+ crazy.should == { 'a' => '1', 'b' => '5' }
126
+
127
+ upsert.row({:name => 'Bill'}, :crazy => {:a => nil, :b => nil, :c => 12})
128
+ row = Pet.connection.select_one(%{SELECT crazy FROM pets WHERE name = 'Bill'})
129
+ crazy = deserializer.parse row['crazy']
130
+ crazy.should == { 'c' => '12' }
131
+ end
132
+
133
+ it "takes dangerous keys" do
134
+ upsert.row({:name => 'Bill'}, :crazy => nil)
135
+ row = Pet.connection.select_one(%{SELECT crazy FROM pets WHERE name = 'Bill'})
136
+ row['crazy'].should == nil
137
+
138
+ upsert.row({:name => 'Bill'}, :crazy => {:'foo"bar' => 1})
139
+ row = Pet.connection.select_one(%{SELECT crazy FROM pets WHERE name = 'Bill'})
140
+ crazy = deserializer.parse row['crazy']
141
+ crazy.should == { 'foo"bar' => '1' }
142
+
143
+ upsert.row({:name => 'Bill'}, :crazy => {})
144
+ row = Pet.connection.select_one(%{SELECT crazy FROM pets WHERE name = 'Bill'})
145
+ crazy = deserializer.parse row['crazy']
146
+ crazy.should == { 'foo"bar' => '1' }
147
+
148
+ upsert.row({:name => 'Bill'}, :crazy => {:'foo"bar' => nil})
149
+ row = Pet.connection.select_one(%{SELECT crazy FROM pets WHERE name = 'Bill'})
150
+ crazy = deserializer.parse row['crazy']
151
+ crazy.should == {}
152
+
153
+ upsert.row({:name => 'Bill'}, :crazy => {:'foo"bar' => 1, :b => 5})
154
+ row = Pet.connection.select_one(%{SELECT crazy FROM pets WHERE name = 'Bill'})
155
+ crazy = deserializer.parse row['crazy']
156
+ crazy.should == { 'foo"bar' => '1', 'b' => '5' }
157
+
158
+ upsert.row({:name => 'Bill'}, :crazy => {})
159
+ row = Pet.connection.select_one(%{SELECT crazy FROM pets WHERE name = 'Bill'})
160
+ crazy = deserializer.parse row['crazy']
161
+ crazy.should == { 'foo"bar' => '1', 'b' => '5' }
162
+
163
+ upsert.row({:name => 'Bill'}, :crazy => {:'foo"bar' => nil})
164
+ row = Pet.connection.select_one(%{SELECT crazy FROM pets WHERE name = 'Bill'})
165
+ crazy = deserializer.parse row['crazy']
166
+ crazy.should == { 'b' => '5' }
167
+
168
+ upsert.row({:name => 'Bill'}, :crazy => {:'foo"bar' => 1, :b => 5})
169
+ row = Pet.connection.select_one(%{SELECT crazy FROM pets WHERE name = 'Bill'})
170
+ crazy = deserializer.parse row['crazy']
171
+ crazy.should == { 'foo"bar' => '1', 'b' => '5' }
172
+
173
+ upsert.row({:name => 'Bill'}, :crazy => {:'foo"bar' => nil, :b => nil, :c => 12})
174
+ row = Pet.connection.select_one(%{SELECT crazy FROM pets WHERE name = 'Bill'})
175
+ crazy = deserializer.parse row['crazy']
176
+ crazy.should == { 'c' => '12' }
177
+ end
178
+
179
+ it "handles multiple hstores" do
180
+ upsert.row({:name => 'Bill'}, :crazy => {:a => 1, :b => 9}, :cool => {:c => 12, :d => 19})
181
+ row = Pet.connection.select_one(%{SELECT crazy, cool FROM pets WHERE name = 'Bill'})
182
+ crazy = deserializer.parse row['crazy']
183
+ crazy.should == { 'a' => '1', 'b' => '9' }
184
+ cool = deserializer.parse row['cool']
185
+ cool.should == { 'c' => '12', 'd' => '19' }
186
+ end
187
+
188
+ it "can deletes keys from multiple hstores at once" do
189
+ upsert.row({:name => 'Bill'}, :crazy => {:a => 1}, :cool => {5 => 9})
190
+ row = Pet.connection.select_one(%{SELECT crazy, cool FROM pets WHERE name = 'Bill'})
191
+ crazy = deserializer.parse row['crazy']
192
+ crazy.should == { 'a' => '1' }
193
+ cool = deserializer.parse row['cool']
194
+ cool.should == { '5' => '9' }
195
+
196
+ # NOOP
197
+ upsert.row({:name => 'Bill'}, :crazy => {}, :cool => {})
198
+ row = Pet.connection.select_one(%{SELECT crazy, cool FROM pets WHERE name = 'Bill'})
199
+ crazy = deserializer.parse row['crazy']
200
+ crazy.should == { 'a' => '1' }
201
+ cool = deserializer.parse row['cool']
202
+ cool.should == { '5' => '9' }
203
+
204
+ upsert.row({:name => 'Bill'}, :crazy => {:a => nil}, :cool => {13 => 17})
205
+ row = Pet.connection.select_one(%{SELECT crazy, cool FROM pets WHERE name = 'Bill'})
206
+ crazy = deserializer.parse row['crazy']
207
+ crazy.should == {}
208
+ cool = deserializer.parse row['cool']
209
+ cool.should == { '5' => '9', '13' => '17' }
210
+
211
+ upsert.row({:name => 'Bill'}, :crazy => {:a => 1, :b => 5})
212
+ row = Pet.connection.select_one(%{SELECT crazy, cool FROM pets WHERE name = 'Bill'})
213
+ crazy = deserializer.parse row['crazy']
214
+ crazy.should == { 'a' => '1', 'b' => '5' }
215
+
216
+ upsert.row({:name => 'Bill'}, :crazy => {:b => nil}, :cool => {5 => nil})
217
+ row = Pet.connection.select_one(%{SELECT crazy, cool FROM pets WHERE name = 'Bill'})
218
+ crazy = deserializer.parse row['crazy']
219
+ crazy.should == {'a' => '1'}
220
+ cool = deserializer.parse row['cool']
221
+ cool.should == {'13' => '17' }
222
+ end
223
+
224
+ it "deletes keys whether new or existing record" do
225
+ upsert.row({:name => 'Bill'}, :crazy => {:z => 1, :x => nil})
226
+ row = Pet.connection.select_one(%{SELECT crazy FROM pets WHERE name = 'Bill'})
227
+ crazy = deserializer.parse row['crazy']
228
+ crazy.should == { 'z' => '1' }
229
+
230
+ upsert.row({:name => 'Bill'}, :crazy => {:a => 1})
231
+ row = Pet.connection.select_one(%{SELECT crazy FROM pets WHERE name = 'Bill'})
232
+ crazy = deserializer.parse row['crazy']
233
+ crazy.should == { 'a' => '1', 'z' => '1' }
234
+ end
235
+
236
+ it "can turn off eager nullify" do
237
+ upsert.row({:name => 'Bill'}, {:crazy => {:z => 1, :x => nil}}, :eager_nullify => false)
238
+ row = Pet.connection.select_one(%{SELECT crazy FROM pets WHERE name = 'Bill'})
239
+ crazy = deserializer.parse row['crazy']
240
+ crazy.should == { 'z' => '1', 'x' => nil }
241
+
242
+ upsert.row({:name => 'Bill'}, :crazy => {:a => 1})
243
+ row = Pet.connection.select_one(%{SELECT crazy FROM pets WHERE name = 'Bill'})
244
+ crazy = deserializer.parse row['crazy']
245
+ crazy.should == { 'a' => '1', 'z' => '1', 'x' => nil}
246
+ end
247
+
248
+ end
249
+ end if ENV['DB'] == 'postgresql'
@@ -0,0 +1,9 @@
1
+ require 'spec_helper'
2
+ describe Upsert do
3
+ it "works correct with large ints" do
4
+ u = Upsert.new($conn, :pets)
5
+ Pet.create(:name => "Jerry", :big_tag_number => 2)
6
+ u.row({ :name => 'Jerry' }, :big_tag_number => 3599657714)
7
+ Pet.find_by_name('Jerry').big_tag_number.should == 3599657714
8
+ end
9
+ end if RUBY_PLATFORM == 'java'
@@ -0,0 +1,52 @@
1
+ require 'spec_helper'
2
+ describe Upsert do
3
+ MUTEX_FOR_PERFORM = Mutex.new
4
+ describe "logger" do
5
+ it "logs where you tell it" do
6
+ begin
7
+ old_logger = Upsert.logger
8
+ io = StringIO.new
9
+ MUTEX_FOR_PERFORM.synchronize do
10
+ Upsert.logger = Logger.new(io)
11
+
12
+ Upsert.logger.warn "hello"
13
+
14
+ io.rewind
15
+ io.read.chomp.should =~ /hello/
16
+ end
17
+ ensure
18
+ Upsert.logger = old_logger
19
+ end
20
+ end
21
+
22
+ it "logs queries" do
23
+ old_logger = Upsert.logger
24
+ begin
25
+ io = StringIO.new
26
+ MUTEX_FOR_PERFORM.synchronize do
27
+ Upsert.logger = Logger.new(io)
28
+
29
+ u = Upsert.new($conn, :pets)
30
+ u.row(:name => 'Jerry')
31
+
32
+ io.rewind
33
+ log = io.read.chomp
34
+ case u.connection.class.name
35
+ when /sqlite/i
36
+ log.should =~ /insert or ignore/i
37
+ when /mysql/i
38
+ log.should =~ /call #{Upsert::MergeFunction::NAME_PREFIX}_pets_SEL_name/i
39
+ when /p.*g/i
40
+ # [54ae2eea857] Possibly much more useful debug output
41
+ # TODO: Should check for both upsert and non-upsert log output
42
+ log.should =~ /selector:|SHOW server_version/i
43
+ else
44
+ raise "not sure"
45
+ end
46
+ end
47
+ ensure
48
+ Upsert.logger = old_logger
49
+ end
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,12 @@
1
+ require 'remote_table'
2
+
3
+ a = RemoteTable.new(
4
+ :url => 'http://www.postgresql.org/docs/9.1/static/sql-keywords-appendix.html',
5
+ :row_css => 'table.CALSTABLE tbody tr',
6
+ :column_css => 'td',
7
+ :headers => %w{ key_word }
8
+ )
9
+
10
+ a.each do |row|
11
+ puts row['key_word']
12
+ end
@@ -0,0 +1,226 @@
1
+ ACCESSIBLE
2
+ ADD
3
+ ALL
4
+ ALTER
5
+ ANALYZE
6
+ AND
7
+ AS
8
+ ASC
9
+ ASENSITIVE
10
+ BEFORE
11
+ BETWEEN
12
+ BIGINT
13
+ BINARY
14
+ BLOB
15
+ BOTH
16
+ BY
17
+ CALL
18
+ CASCADE
19
+ CASE
20
+ CHANGE
21
+ CHAR
22
+ CHARACTER
23
+ CHECK
24
+ COLLATE
25
+ COLUMN
26
+ CONDITION
27
+ CONSTRAINT
28
+ CONTINUE
29
+ CONVERT
30
+ CREATE
31
+ CROSS
32
+ CURRENT_DATE
33
+ CURRENT_TIME
34
+ CURRENT_TIMESTAMP
35
+ CURRENT_USER
36
+ CURSOR
37
+ DATABASE
38
+ DATABASES
39
+ DAY_HOUR
40
+ DAY_MICROSECOND
41
+ DAY_MINUTE
42
+ DAY_SECOND
43
+ DEC
44
+ DECIMAL
45
+ DECLARE
46
+ DEFAULT
47
+ DELAYED
48
+ DELETE
49
+ DESC
50
+ DESCRIBE
51
+ DETERMINISTIC
52
+ DISTINCT
53
+ DISTINCTROW
54
+ DIV
55
+ DOUBLE
56
+ DROP
57
+ DUAL
58
+ EACH
59
+ ELSE
60
+ ELSEIF
61
+ ENCLOSED
62
+ ESCAPED
63
+ EXISTS
64
+ EXIT
65
+ EXPLAIN
66
+ FALSE
67
+ FETCH
68
+ FLOAT
69
+ FLOAT4
70
+ FLOAT8
71
+ FOR
72
+ FORCE
73
+ FOREIGN
74
+ FROM
75
+ FULLTEXT
76
+ GRANT
77
+ GROUP
78
+ HAVING
79
+ HIGH_PRIORITY
80
+ HOUR_MICROSECOND
81
+ HOUR_MINUTE
82
+ HOUR_SECOND
83
+ IF
84
+ IGNORE
85
+ IN
86
+ INDEX
87
+ INFILE
88
+ INNER
89
+ INOUT
90
+ INSENSITIVE
91
+ INSERT
92
+ INT
93
+ INT1
94
+ INT2
95
+ INT3
96
+ INT4
97
+ INT8
98
+ INTEGER
99
+ INTERVAL
100
+ INTO
101
+ IS
102
+ ITERATE
103
+ JOIN
104
+ KEY
105
+ KEYS
106
+ KILL
107
+ LEADING
108
+ LEAVE
109
+ LEFT
110
+ LIKE
111
+ LIMIT
112
+ LINEAR
113
+ LINES
114
+ LOAD
115
+ LOCALTIME
116
+ LOCALTIMESTAMP
117
+ LOCK
118
+ LONG
119
+ LONGBLOB
120
+ LONGTEXT
121
+ LOOP
122
+ LOW_PRIORITY
123
+ MASTER_SSL_VERIFY_SERVER_CERT
124
+ MATCH
125
+ MAXVALUE
126
+ MEDIUMBLOB
127
+ MEDIUMINT
128
+ MEDIUMTEXT
129
+ MIDDLEINT
130
+ MINUTE_MICROSECOND
131
+ MINUTE_SECOND
132
+ MOD
133
+ MODIFIES
134
+ NATURAL
135
+ NOT
136
+ NO_WRITE_TO_BINLOG
137
+ NULL
138
+ NUMERIC
139
+ ON
140
+ OPTIMIZE
141
+ OPTION
142
+ OPTIONALLY
143
+ OR
144
+ ORDER
145
+ OUT
146
+ OUTER
147
+ OUTFILE
148
+ PRECISION
149
+ PRIMARY
150
+ PROCEDURE
151
+ PURGE
152
+ RANGE
153
+ READ
154
+ READS
155
+ READ_WRITE
156
+ REAL
157
+ REFERENCES
158
+ REGEXP
159
+ RELEASE
160
+ RENAME
161
+ REPEAT
162
+ REPLACE
163
+ REQUIRE
164
+ RESIGNAL
165
+ RESTRICT
166
+ RETURN
167
+ REVOKE
168
+ RIGHT
169
+ RLIKE
170
+ SCHEMA
171
+ SCHEMAS
172
+ SECOND_MICROSECOND
173
+ SELECT
174
+ SENSITIVE
175
+ SEPARATOR
176
+ SET
177
+ SHOW
178
+ SIGNAL
179
+ SMALLINT
180
+ SPATIAL
181
+ SPECIFIC
182
+ SQL
183
+ SQLEXCEPTION
184
+ SQLSTATE
185
+ SQLWARNING
186
+ SQL_BIG_RESULT
187
+ SQL_CALC_FOUND_ROWS
188
+ SQL_SMALL_RESULT
189
+ SSL
190
+ STARTING
191
+ STRAIGHT_JOIN
192
+ TABLE
193
+ TERMINATED
194
+ THEN
195
+ TINYBLOB
196
+ TINYINT
197
+ TINYTEXT
198
+ TO
199
+ TRAILING
200
+ TRIGGER
201
+ TRUE
202
+ UNDO
203
+ UNION
204
+ UNIQUE
205
+ UNLOCK
206
+ UNSIGNED
207
+ UPDATE
208
+ USAGE
209
+ USE
210
+ USING
211
+ UTC_DATE
212
+ UTC_TIME
213
+ UTC_TIMESTAMP
214
+ VALUES
215
+ VARBINARY
216
+ VARCHAR
217
+ VARCHARACTER
218
+ VARYING
219
+ WHEN
220
+ WHERE
221
+ WHILE
222
+ WITH
223
+ WRITE
224
+ XOR
225
+ YEAR_MONTH
226
+ ZEROFILL