upsert 2.0.2 → 2.0.3
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.
- 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
|