upsert 2.0.2 → 2.0.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +8 -8
- data/CHANGELOG +12 -0
- data/lib/upsert.rb +2 -2
- data/lib/upsert/column_definition.rb +10 -6
- data/lib/upsert/column_definition/postgresql.rb +4 -3
- data/lib/upsert/column_definition/sqlite3.rb +1 -1
- data/lib/upsert/row.rb +4 -2
- data/lib/upsert/version.rb +1 -1
- data/spec/correctness_spec.rb +15 -4
- data/spec/hstore_spec.rb +14 -0
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
ZWU3NjI3M2VmZDY1YzVlNGMyMzA5NWI3ZTQyNjVkNzZkNjE4MWMwNA==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
MTIzNjU4OGIxMmYwNzliZGY1OWVkYTA5ZWUxNzk1ZDViMjg0Mzg1NQ==
|
7
7
|
SHA512:
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
ODFiNzk2M2MwMTQwNWFkYmQ1MDhkMmFlNTRkMzg5MDI2ZDNlZjAzNzhiY2Yx
|
10
|
+
MmE1NTVhMzYzZjBjYTQyZTkzY2U3Y2M5M2M4OTU0MjVkNGE1YWFlY2U2NTU0
|
11
|
+
ZWJiZjA1YjdiMzM2ZjdmNGU3NThkZTcxMzA4MjdiYzk0OTA3MDc=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
MDlhYzkxZjg5NThiMDNkY2I5YTE2ODViNGQ2NzM5ZjU0OTk3ODdiMDMwOTNm
|
14
|
+
NTYwNTUxMTEyMjIwMTdmNGRlYzc4MDg5NWUzOGExYWI3ZDQ0OGUwNDg1Njlk
|
15
|
+
NGIxY2NkMzc2YjE5OWNlMmNkZmRhMjFlOGIxMmU5MmY1ZDZjN2U=
|
data/CHANGELOG
CHANGED
@@ -1,4 +1,16 @@
|
|
1
|
+
2.0.3 / 2013-11-27
|
2
|
+
|
3
|
+
* Bug fixes
|
4
|
+
|
5
|
+
* Add parentheses to equality expressions
|
6
|
+
|
7
|
+
* Enhancements
|
8
|
+
|
9
|
+
* On Postgres, use (A = B OR (A IS NULL AND B IS NULL)) instead of A IS NOT DISTINCT FROM B because the latter does not use indexes
|
10
|
+
* pass :eager_nullify => false as the third argument to Upsert#row to disable clearing of null HStore keys
|
11
|
+
|
1
12
|
2.0.2 / 2013-11-06
|
13
|
+
|
2
14
|
* Bug fixes
|
3
15
|
|
4
16
|
* Properly check for NULL equality when creating the UPSERT functions - thanks @pnomolos - https://github.com/seamusabshere/upsert/issues/25
|
data/lib/upsert.rb
CHANGED
@@ -212,8 +212,8 @@ class Upsert
|
|
212
212
|
# upsert = Upsert.new Pet.connection, Pet.table_name
|
213
213
|
# upsert.row({:name => 'Jerry'}, :breed => 'beagle')
|
214
214
|
# upsert.row({:name => 'Pierre'}, :breed => 'tabby')
|
215
|
-
def row(selector, setter = {})
|
216
|
-
merge_function_class.execute self, Row.new(selector, setter)
|
215
|
+
def row(selector, setter = {}, options = nil)
|
216
|
+
merge_function_class.execute self, Row.new(selector, setter, options)
|
217
217
|
nil
|
218
218
|
end
|
219
219
|
|
@@ -40,11 +40,7 @@ class Upsert
|
|
40
40
|
end
|
41
41
|
|
42
42
|
def to_selector
|
43
|
-
|
44
|
-
"#{quoted_name} = CAST(#{quoted_selector_name} AS #{sql_type})"
|
45
|
-
else
|
46
|
-
equality(quoted_name, quoted_selector_name)
|
47
|
-
end
|
43
|
+
equality(quoted_name, to_selector_value)
|
48
44
|
end
|
49
45
|
|
50
46
|
def temporal?
|
@@ -52,7 +48,7 @@ class Upsert
|
|
52
48
|
end
|
53
49
|
|
54
50
|
def equality(left, right)
|
55
|
-
"#{left} = #{right}"
|
51
|
+
"(#{left} = #{right} OR (#{left} IS NULL AND #{right} IS NULL))"
|
56
52
|
end
|
57
53
|
|
58
54
|
def arg_type
|
@@ -71,5 +67,13 @@ class Upsert
|
|
71
67
|
end
|
72
68
|
end
|
73
69
|
|
70
|
+
def to_selector_value
|
71
|
+
if temporal?
|
72
|
+
"CAST(#{quoted_selector_name} AS #{sql_type})"
|
73
|
+
else
|
74
|
+
quoted_selector_name
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
74
78
|
end
|
75
79
|
end
|
@@ -20,9 +20,10 @@ EOS
|
|
20
20
|
end
|
21
21
|
end
|
22
22
|
|
23
|
-
|
24
|
-
|
25
|
-
|
23
|
+
# NOTE not using this because it can't be indexed
|
24
|
+
# def equality(left, right)
|
25
|
+
# "#{left} IS NOT DISTINCT FROM #{right}"
|
26
|
+
# end
|
26
27
|
|
27
28
|
HSTORE_DETECTOR = /hstore/i
|
28
29
|
|
data/lib/upsert/row.rb
CHANGED
@@ -16,7 +16,9 @@ class Upsert
|
|
16
16
|
attr_reader :setter
|
17
17
|
attr_reader :hstore_delete_keys
|
18
18
|
|
19
|
-
def initialize(raw_selector, raw_setter)
|
19
|
+
def initialize(raw_selector, raw_setter, options)
|
20
|
+
eager_nullify = (options.nil? || options.fetch(:eager_nullify, true))
|
21
|
+
|
20
22
|
@selector = raw_selector.inject({}) do |memo, (k, v)|
|
21
23
|
memo[k.to_s] = v
|
22
24
|
memo
|
@@ -25,7 +27,7 @@ class Upsert
|
|
25
27
|
@hstore_delete_keys = {}
|
26
28
|
@setter = raw_setter.inject({}) do |memo, (k, v)|
|
27
29
|
k = k.to_s
|
28
|
-
if v.is_a?(::Hash)
|
30
|
+
if v.is_a?(::Hash) and eager_nullify
|
29
31
|
v.each do |kk, vv|
|
30
32
|
if vv.nil?
|
31
33
|
(@hstore_delete_keys[k] ||= []) << kk
|
data/lib/upsert/version.rb
CHANGED
data/spec/correctness_spec.rb
CHANGED
@@ -50,20 +50,31 @@ describe Upsert do
|
|
50
50
|
# https://github.com/seamusabshere/upsert/issues/18
|
51
51
|
it "uses nil selectors" do
|
52
52
|
Pet.count.should == 0
|
53
|
-
now =
|
53
|
+
now = Date.today
|
54
54
|
u = Upsert.new($conn, :pets)
|
55
55
|
5.times do
|
56
|
-
u.row(
|
56
|
+
u.row(gender: nil, birthday: now)
|
57
57
|
end
|
58
|
+
|
59
|
+
Pet.count.should == 1
|
60
|
+
end
|
61
|
+
|
62
|
+
it "uses nil selectors on columns with date type" do
|
63
|
+
Pet.count.should == 0
|
64
|
+
u = Upsert.new($conn, :pets)
|
65
|
+
5.times do
|
66
|
+
u.row(birthday: nil)
|
67
|
+
end
|
68
|
+
|
58
69
|
Pet.count.should == 1
|
59
70
|
end
|
60
71
|
|
61
72
|
it "uses nil selectors (another way of checking)" do
|
62
73
|
u = Upsert.new($conn, :pets)
|
63
|
-
now =
|
74
|
+
now = Date.today
|
64
75
|
assert_creates(Pet, [{:name => 'Jerry', :gender => nil, :spiel => 'beagle', :birthday => now}]) do
|
65
76
|
u.row(name: "Jerry", gender: nil, spiel: "samoyed")
|
66
|
-
u.row({:name => 'Jerry', gender: nil}, :spiel => 'beagle', :birthday =>
|
77
|
+
u.row({:name => 'Jerry', gender: nil}, :spiel => 'beagle', :birthday => now)
|
67
78
|
end
|
68
79
|
end
|
69
80
|
|
data/spec/hstore_spec.rb
CHANGED
@@ -230,5 +230,19 @@ EOS
|
|
230
230
|
crazy.should == { 'a' => '1', 'z' => '1' }
|
231
231
|
end
|
232
232
|
|
233
|
+
it "can turn off eager nullify" do
|
234
|
+
upsert = Upsert.new $conn, :pets
|
235
|
+
|
236
|
+
upsert.row({name: 'Bill'}, {crazy: {z: 1, x: nil}}, eager_nullify: false)
|
237
|
+
row = Pet.connection.select_one(%{SELECT crazy FROM pets WHERE name = 'Bill'})
|
238
|
+
crazy = PgHstore.parse row['crazy']
|
239
|
+
crazy.should == { 'z' => '1', 'x' => nil }
|
240
|
+
|
241
|
+
upsert.row({name: 'Bill'}, crazy: {a: 1})
|
242
|
+
row = Pet.connection.select_one(%{SELECT crazy FROM pets WHERE name = 'Bill'})
|
243
|
+
crazy = PgHstore.parse row['crazy']
|
244
|
+
crazy.should == { 'a' => '1', 'z' => '1', 'x' => nil}
|
245
|
+
end
|
246
|
+
|
233
247
|
end
|
234
248
|
end if ENV['DB'] == 'postgresql'
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: upsert
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.0.
|
4
|
+
version: 2.0.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Seamus Abshere
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-11-
|
11
|
+
date: 2013-11-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rspec-core
|
@@ -317,7 +317,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
317
317
|
version: '0'
|
318
318
|
requirements: []
|
319
319
|
rubyforge_project:
|
320
|
-
rubygems_version: 2.1.
|
320
|
+
rubygems_version: 2.1.11
|
321
321
|
signing_key:
|
322
322
|
specification_version: 4
|
323
323
|
summary: Make it easy to upsert on MySQL, PostgreSQL, and SQLite3. Transparently creates
|