upsert 2.9.10-java

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 (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