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 CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- ZmE1OGFkMDI2YWQ2NmY2YjBmYzdiOWUzNDhjN2ZjNzY5MGVkYmMxZg==
4
+ ZWU3NjI3M2VmZDY1YzVlNGMyMzA5NWI3ZTQyNjVkNzZkNjE4MWMwNA==
5
5
  data.tar.gz: !binary |-
6
- NzNjZjVmODZiNWE2NzdlNzg3M2FkZDg0ZDNiNDkyMjU4NGY0MDkxNg==
6
+ MTIzNjU4OGIxMmYwNzliZGY1OWVkYTA5ZWUxNzk1ZDViMjg0Mzg1NQ==
7
7
  SHA512:
8
8
  metadata.gz: !binary |-
9
- MWMzOTcwYmMxMzllMTMyZjY0Nzg3OTZmMTUyMmM4NDM4MTkxNTBjNmFiZDNk
10
- NGZkYjg3MDVmYTMxM2Y5M2Q0MGYyY2I0NTZlNzAxNDkzYjk5NGJmM2E5ZmMx
11
- ZWYzZmU3ODU1NTRiOWQyNzEyY2M1MzYyMDIzMTUxODE5MDQ2MDA=
9
+ ODFiNzk2M2MwMTQwNWFkYmQ1MDhkMmFlNTRkMzg5MDI2ZDNlZjAzNzhiY2Yx
10
+ MmE1NTVhMzYzZjBjYTQyZTkzY2U3Y2M5M2M4OTU0MjVkNGE1YWFlY2U2NTU0
11
+ ZWJiZjA1YjdiMzM2ZjdmNGU3NThkZTcxMzA4MjdiYzk0OTA3MDc=
12
12
  data.tar.gz: !binary |-
13
- NjJiNjBiOGE3N2JjMzVjMTEyY2MwMTMwZTZhZmEzYTk2ZmNhMTVlOTdiMTAw
14
- MjQxMTQ2ODU0ZGFlMWEzODBjOTVmMjAzMjlmZWI1ZjAwNmFkMTJhZjUzZTU0
15
- OTEyZWQ3OWNlM2RiNWRmNjgxYmEzZWJlZTU5ZDdhYTg3ODU2Nzc=
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
@@ -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
- if temporal?
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
- def equality(left, right)
24
- "#{left} IS NOT DISTINCT FROM #{right}"
25
- end
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
 
@@ -27,7 +27,7 @@ class Upsert
27
27
  end
28
28
 
29
29
  def equality(left, right)
30
- "#{left} IS #{right} OR (#{left} IS NULL AND #{right} IS NULL)"
30
+ "(#{left} IS #{right} OR (#{left} IS NULL AND #{right} IS NULL))"
31
31
  end
32
32
  end
33
33
  end
@@ -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
@@ -1,3 +1,3 @@
1
1
  class Upsert
2
- VERSION = '2.0.2'
2
+ VERSION = '2.0.3'
3
3
  end
@@ -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 = Time.now
53
+ now = Date.today
54
54
  u = Upsert.new($conn, :pets)
55
55
  5.times do
56
- u.row({gender: nil, birthday: now})
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 = Time.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 => Time.now)
77
+ u.row({:name => 'Jerry', gender: nil}, :spiel => 'beagle', :birthday => now)
67
78
  end
68
79
  end
69
80
 
@@ -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.2
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-06 00:00:00.000000000 Z
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.5
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