upsert 2.0.1 → 2.0.2

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.
@@ -0,0 +1,15 @@
1
+ ---
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ ZmE1OGFkMDI2YWQ2NmY2YjBmYzdiOWUzNDhjN2ZjNzY5MGVkYmMxZg==
5
+ data.tar.gz: !binary |-
6
+ NzNjZjVmODZiNWE2NzdlNzg3M2FkZDg0ZDNiNDkyMjU4NGY0MDkxNg==
7
+ SHA512:
8
+ metadata.gz: !binary |-
9
+ MWMzOTcwYmMxMzllMTMyZjY0Nzg3OTZmMTUyMmM4NDM4MTkxNTBjNmFiZDNk
10
+ NGZkYjg3MDVmYTMxM2Y5M2Q0MGYyY2I0NTZlNzAxNDkzYjk5NGJmM2E5ZmMx
11
+ ZWYzZmU3ODU1NTRiOWQyNzEyY2M1MzYyMDIzMTUxODE5MDQ2MDA=
12
+ data.tar.gz: !binary |-
13
+ NjJiNjBiOGE3N2JjMzVjMTEyY2MwMTMwZTZhZmEzYTk2ZmNhMTVlOTdiMTAw
14
+ MjQxMTQ2ODU0ZGFlMWEzODBjOTVmMjAzMjlmZWI1ZjAwNmFkMTJhZjUzZTU0
15
+ OTEyZWQ3OWNlM2RiNWRmNjgxYmEzZWJlZTU5ZDdhYTg3ODU2Nzc=
data/CHANGELOG CHANGED
@@ -1,3 +1,9 @@
1
+ 2.0.2 / 2013-11-06
2
+ * Bug fixes
3
+
4
+ * Properly check for NULL equality when creating the UPSERT functions - thanks @pnomolos - https://github.com/seamusabshere/upsert/issues/25
5
+ * When using Mysql2 client (MRI), don't pass timezone to DateTime columns - thanks @kjeremy! - https://github.com/seamusabshere/upsert/issues/24
6
+
1
7
  2.0.1 / 2013-07-24
2
8
 
3
9
  * Bug fixes
data/README.md CHANGED
@@ -8,6 +8,8 @@ As databases start to natively support SQL MERGE (which is basically upsert), th
8
8
 
9
9
  Does **not** depend on ActiveRecord.
10
10
 
11
+ Does **not** use `INSERT ON DUPLICATE KEY UPDATE` on MySQL as this only works if you are very careful about creating unique indexes.
12
+
11
13
  70–90%+ faster than emulating upsert with ActiveRecord.
12
14
 
13
15
  Supports MRI and JRuby.
@@ -80,14 +82,9 @@ upsert.row_with_two_setter(update_setter, insert_setter, selector)
80
82
 
81
83
  ## Real-world usage
82
84
 
83
- <p><a href="http://brighterplanet.com"><img src="https://s3.amazonaws.com/static.brighterplanet.com/assets/logos/flush-left/inline/green/rasterized/brighter_planet-160-transparent.png" alt="Brighter Planet logo"/></a></p>
84
-
85
- We use `upsert` for [big data processing at Brighter Planet](http://brighterplanet.com/research) and in production at
85
+ <p><a href="http://angel.co/faraday"><img src="https://s3.amazonaws.com/photos.angel.co/startups/i/175701-a63ebd1b56a401e905963c64958204d4-medium_jpg.jpg" alt="Faraday logo"/></a></p>
86
86
 
87
- * [Brighter Planet's impact estimate web service](http://impact.brighterplanet.com)
88
- * [Brighter Planet's reference data web service](http://data.brighterplanet.com)
89
-
90
- Originally written to speed up the [`data_miner`](https://github.com/seamusabshere/data_miner) data mining library.
87
+ We use `upsert` for [big data at Faraday](http://angel.co/faraday). Originally written to speed up the [`data_miner`](https://github.com/seamusabshere/data_miner) data mining library.
91
88
 
92
89
  ## Supported databases/drivers
93
90
 
@@ -307,6 +304,8 @@ From the tests (updated 9/21/12):
307
304
 
308
305
  Thanks to [@dan04's answer on StackOverflow](http://stackoverflow.com/questions/2717590/sqlite-upsert-on-duplicate-key-update):
309
306
 
307
+ **Please note! This will only work properly on Sqlite if one of the columns being used as the "selector" are a primary key or unique index**
308
+
310
309
  ```sql
311
310
  INSERT OR IGNORE INTO visits VALUES (127.0.0.1, 1);
312
311
  UPDATE visits SET visits = 1 WHERE ip LIKE 127.0.0.1;
@@ -360,7 +359,10 @@ If you're using MySQL, make sure server/connection timezone is UTC. If you're us
360
359
 
361
360
  In general, run some upserts and make sure datetimes get persisted like you expect.
362
361
 
363
- ## Copyright
362
+ ### Doesn't work with transactional fixtures
363
+
364
+ Per https://github.com/seamusabshere/upsert/issues/23 you might have issues if you try to use transactional fixtures and this library.
364
365
 
365
- Copyright 2012 Seamus Abshere
366
+ ## Copyright
366
367
 
368
+ Copyright 2013 Seamus Abshere
data/Rakefile CHANGED
@@ -3,7 +3,13 @@ require "bundler/gem_tasks"
3
3
 
4
4
  task :rspec_all_databases do
5
5
  results = {}
6
- %w{ postgresql mysql sqlite3 }.each do |db|
6
+
7
+ dbs = %w{ postgresql mysql sqlite3 }
8
+ if ENV['DB']
9
+ dbs = ENV['DB'].split(',')
10
+ end
11
+
12
+ dbs.each do |db|
7
13
  puts
8
14
  puts '#'*50
9
15
  puts "# Running specs against #{db}"
@@ -43,7 +43,7 @@ class Upsert
43
43
  if temporal?
44
44
  "#{quoted_name} = CAST(#{quoted_selector_name} AS #{sql_type})"
45
45
  else
46
- "#{quoted_name} = #{quoted_selector_name}"
46
+ equality(quoted_name, quoted_selector_name)
47
47
  end
48
48
  end
49
49
 
@@ -51,6 +51,10 @@ class Upsert
51
51
  @temporal_query
52
52
  end
53
53
 
54
+ def equality(left, right)
55
+ "#{left} = #{right}"
56
+ end
57
+
54
58
  def arg_type
55
59
  if temporal?
56
60
  'character varying(255)'
@@ -15,6 +15,10 @@ class Upsert
15
15
  end
16
16
  end
17
17
  end
18
+
19
+ def equality(left, right)
20
+ "#{left} <=> #{right}"
21
+ end
18
22
  end
19
23
  end
20
24
  end
@@ -19,6 +19,10 @@ EOS
19
19
  end
20
20
  end
21
21
  end
22
+
23
+ def equality(left, right)
24
+ "#{left} IS NOT DISTINCT FROM #{right}"
25
+ end
22
26
 
23
27
  HSTORE_DETECTOR = /hstore/i
24
28
 
@@ -25,6 +25,10 @@ class Upsert
25
25
  end
26
26
  end
27
27
  end
28
+
29
+ def equality(left, right)
30
+ "#{left} IS #{right} OR (#{left} IS NULL AND #{right} IS NULL)"
31
+ end
28
32
  end
29
33
  end
30
34
  end
@@ -34,7 +34,8 @@ class Upsert
34
34
  when Symbol
35
35
  quote_string v.to_s
36
36
  when DateTime, Time
37
- quote_string Upsert.utc_iso8601(v) #round?
37
+ # mysql doesn't like it when you send timezone to a datetime
38
+ quote_string Upsert.utc_iso8601(v, false)
38
39
  when Date
39
40
  quote_date v
40
41
  else
@@ -6,7 +6,7 @@ class Upsert
6
6
 
7
7
  def execute(sql, params = nil)
8
8
  if params
9
- Upsert.logger.debug { %{[upsert] #{sql} with #{params.inspect}} }
9
+ # Upsert.logger.debug { %{[upsert] #{sql} with #{params.inspect}} }
10
10
  metal.exec sql, convert_binary(params)
11
11
  else
12
12
  Upsert.logger.debug { %{[upsert] #{sql}} }
@@ -14,6 +14,9 @@ class Upsert
14
14
  hstore_delete_handlers.each do |hstore_delete_handler|
15
15
  values << row.hstore_delete_keys.fetch(hstore_delete_handler.name, [])
16
16
  end
17
+ Upsert.logger.debug do
18
+ %{[upsert]\n\tSelector: #{row.selector.inspect}\n\tSetter: #{row.setter.inspect}}
19
+ end
17
20
  begin
18
21
  connection.execute sql, values.map { |v| connection.bind_value v }
19
22
  rescue PG::Error => pg_error
@@ -1,3 +1,3 @@
1
1
  class Upsert
2
- VERSION = '2.0.1'
2
+ VERSION = '2.0.2'
3
3
  end
@@ -49,9 +49,12 @@ describe Upsert do
49
49
 
50
50
  # https://github.com/seamusabshere/upsert/issues/18
51
51
  it "uses nil selectors" do
52
- Pet.create(name: "Jerry", gender: nil, spiel: "samoyed")
52
+ Pet.count.should == 0
53
+ now = Time.now
53
54
  u = Upsert.new($conn, :pets)
54
- u.row({:name => 'Jerry', gender: nil}, :spiel => 'beagle', :birthday => Time.now)
55
+ 5.times do
56
+ u.row({gender: nil, birthday: now})
57
+ end
55
58
  Pet.count.should == 1
56
59
  end
57
60
 
@@ -19,7 +19,7 @@ EOS
19
19
  upsert.row({:name => 'Uggy'}, crazy: {uggy: uggy})
20
20
  row = Pet.connection.select_one(%{SELECT crazy FROM pets WHERE name = 'Uggy'})
21
21
  crazy = PgHstore.parse row['crazy']
22
- crazy.should == { uggy: uggy }
22
+ crazy.should == { 'uggy' => uggy }
23
23
  end
24
24
 
25
25
  it "just works" do
@@ -32,7 +32,7 @@ EOS
32
32
  upsert.row({name: 'Bill'}, crazy: {a: 1})
33
33
  row = Pet.connection.select_one(%{SELECT crazy FROM pets WHERE name = 'Bill'})
34
34
  crazy = PgHstore.parse row['crazy']
35
- crazy.should == { a: '1' }
35
+ crazy.should == { 'a' => '1' }
36
36
 
37
37
  upsert.row({name: 'Bill'}, crazy: nil)
38
38
  row = Pet.connection.select_one(%{SELECT crazy FROM pets WHERE name = 'Bill'})
@@ -41,22 +41,22 @@ EOS
41
41
  upsert.row({name: 'Bill'}, crazy: {a: 1})
42
42
  row = Pet.connection.select_one(%{SELECT crazy FROM pets WHERE name = 'Bill'})
43
43
  crazy = PgHstore.parse row['crazy']
44
- crazy.should == { a: '1' }
44
+ crazy.should == { 'a' => '1' }
45
45
 
46
46
  upsert.row({name: 'Bill'}, crazy: {whatdat: 'whodat'})
47
47
  row = Pet.connection.select_one(%{SELECT crazy FROM pets WHERE name = 'Bill'})
48
48
  crazy = PgHstore.parse row['crazy']
49
- crazy.should == { a: '1', whatdat: 'whodat' }
49
+ crazy.should == { 'a' => '1', 'whatdat' => 'whodat' }
50
50
 
51
51
  upsert.row({name: 'Bill'}, crazy: {whatdat: "D'ONOFRIO"})
52
52
  row = Pet.connection.select_one(%{SELECT crazy FROM pets WHERE name = 'Bill'})
53
53
  crazy = PgHstore.parse row['crazy']
54
- crazy.should == { a: '1', whatdat: "D'ONOFRIO" }
54
+ crazy.should == { 'a' => '1', 'whatdat' => "D'ONOFRIO" }
55
55
 
56
56
  upsert.row({name: 'Bill'}, crazy: {a: 2})
57
57
  row = Pet.connection.select_one(%{SELECT crazy FROM pets WHERE name = 'Bill'})
58
58
  crazy = PgHstore.parse row['crazy']
59
- crazy.should == { a: '2', whatdat: "D'ONOFRIO" }
59
+ crazy.should == { 'a' => '2', 'whatdat' => "D'ONOFRIO" }
60
60
  end
61
61
 
62
62
  it "can nullify entire hstore" do
@@ -65,7 +65,7 @@ EOS
65
65
  upsert.row({name: 'Bill'}, crazy: {a: 1})
66
66
  row = Pet.connection.select_one(%{SELECT crazy FROM pets WHERE name = 'Bill'})
67
67
  crazy = PgHstore.parse row['crazy']
68
- crazy.should == { a: '1' }
68
+ crazy.should == { 'a' => '1' }
69
69
 
70
70
  upsert.row({name: 'Bill'}, crazy: nil)
71
71
  row = Pet.connection.select_one(%{SELECT crazy FROM pets WHERE name = 'Bill'})
@@ -82,12 +82,12 @@ EOS
82
82
  upsert.row({name: 'Bill'}, crazy: {a: 1})
83
83
  row = Pet.connection.select_one(%{SELECT crazy FROM pets WHERE name = 'Bill'})
84
84
  crazy = PgHstore.parse row['crazy']
85
- crazy.should == { a: '1' }
85
+ crazy.should == { 'a' => '1' }
86
86
 
87
87
  upsert.row({name: 'Bill'}, crazy: {})
88
88
  row = Pet.connection.select_one(%{SELECT crazy FROM pets WHERE name = 'Bill'})
89
89
  crazy = PgHstore.parse row['crazy']
90
- crazy.should == { a: '1' }
90
+ crazy.should == { 'a' => '1' }
91
91
 
92
92
  upsert.row({name: 'Bill'}, crazy: {a: nil})
93
93
  row = Pet.connection.select_one(%{SELECT crazy FROM pets WHERE name = 'Bill'})
@@ -97,27 +97,27 @@ EOS
97
97
  upsert.row({name: 'Bill'}, crazy: {a: 1, b: 5})
98
98
  row = Pet.connection.select_one(%{SELECT crazy FROM pets WHERE name = 'Bill'})
99
99
  crazy = PgHstore.parse row['crazy']
100
- crazy.should == { a: '1', b: '5' }
100
+ crazy.should == { 'a' => '1', 'b' => '5' }
101
101
 
102
102
  upsert.row({name: 'Bill'}, crazy: {})
103
103
  row = Pet.connection.select_one(%{SELECT crazy FROM pets WHERE name = 'Bill'})
104
104
  crazy = PgHstore.parse row['crazy']
105
- crazy.should == { a: '1', b: '5' }
105
+ crazy.should == { 'a' => '1', 'b' => '5' }
106
106
 
107
107
  upsert.row({name: 'Bill'}, crazy: {a: nil})
108
108
  row = Pet.connection.select_one(%{SELECT crazy FROM pets WHERE name = 'Bill'})
109
109
  crazy = PgHstore.parse row['crazy']
110
- crazy.should == { b: '5' }
110
+ crazy.should == { 'b' => '5' }
111
111
 
112
112
  upsert.row({name: 'Bill'}, crazy: {a: 1, b: 5})
113
113
  row = Pet.connection.select_one(%{SELECT crazy FROM pets WHERE name = 'Bill'})
114
114
  crazy = PgHstore.parse row['crazy']
115
- crazy.should == { a: '1', b: '5' }
115
+ crazy.should == { 'a' => '1', 'b' => '5' }
116
116
 
117
117
  upsert.row({name: 'Bill'}, crazy: {a: nil, b: nil, c: 12})
118
118
  row = Pet.connection.select_one(%{SELECT crazy FROM pets WHERE name = 'Bill'})
119
119
  crazy = PgHstore.parse row['crazy']
120
- crazy.should == { c: '12' }
120
+ crazy.should == { 'c' => '12' }
121
121
  end
122
122
 
123
123
  it "takes dangerous keys" do
@@ -130,12 +130,12 @@ EOS
130
130
  upsert.row({name: 'Bill'}, crazy: {:'foo"bar' => 1})
131
131
  row = Pet.connection.select_one(%{SELECT crazy FROM pets WHERE name = 'Bill'})
132
132
  crazy = PgHstore.parse row['crazy']
133
- crazy.should == { :'foo"bar' => '1' }
133
+ crazy.should == { 'foo"bar' => '1' }
134
134
 
135
135
  upsert.row({name: 'Bill'}, crazy: {})
136
136
  row = Pet.connection.select_one(%{SELECT crazy FROM pets WHERE name = 'Bill'})
137
137
  crazy = PgHstore.parse row['crazy']
138
- crazy.should == { :'foo"bar' => '1' }
138
+ crazy.should == { 'foo"bar' => '1' }
139
139
 
140
140
  upsert.row({name: 'Bill'}, crazy: {:'foo"bar' => nil})
141
141
  row = Pet.connection.select_one(%{SELECT crazy FROM pets WHERE name = 'Bill'})
@@ -145,27 +145,27 @@ EOS
145
145
  upsert.row({name: 'Bill'}, crazy: {:'foo"bar' => 1, b: 5})
146
146
  row = Pet.connection.select_one(%{SELECT crazy FROM pets WHERE name = 'Bill'})
147
147
  crazy = PgHstore.parse row['crazy']
148
- crazy.should == { :'foo"bar' => '1', b: '5' }
148
+ crazy.should == { 'foo"bar' => '1', 'b' => '5' }
149
149
 
150
150
  upsert.row({name: 'Bill'}, crazy: {})
151
151
  row = Pet.connection.select_one(%{SELECT crazy FROM pets WHERE name = 'Bill'})
152
152
  crazy = PgHstore.parse row['crazy']
153
- crazy.should == { :'foo"bar' => '1', b: '5' }
153
+ crazy.should == { 'foo"bar' => '1', 'b' => '5' }
154
154
 
155
155
  upsert.row({name: 'Bill'}, crazy: {:'foo"bar' => nil})
156
156
  row = Pet.connection.select_one(%{SELECT crazy FROM pets WHERE name = 'Bill'})
157
157
  crazy = PgHstore.parse row['crazy']
158
- crazy.should == { b: '5' }
158
+ crazy.should == { 'b' => '5' }
159
159
 
160
160
  upsert.row({name: 'Bill'}, crazy: {:'foo"bar' => 1, b: 5})
161
161
  row = Pet.connection.select_one(%{SELECT crazy FROM pets WHERE name = 'Bill'})
162
162
  crazy = PgHstore.parse row['crazy']
163
- crazy.should == { :'foo"bar' => '1', b: '5' }
163
+ crazy.should == { 'foo"bar' => '1', 'b' => '5' }
164
164
 
165
165
  upsert.row({name: 'Bill'}, crazy: {:'foo"bar' => nil, b: nil, c: 12})
166
166
  row = Pet.connection.select_one(%{SELECT crazy FROM pets WHERE name = 'Bill'})
167
167
  crazy = PgHstore.parse row['crazy']
168
- crazy.should == { c: '12' }
168
+ crazy.should == { 'c' => '12' }
169
169
  end
170
170
 
171
171
  it "handles multiple hstores" do
@@ -173,9 +173,9 @@ EOS
173
173
  upsert.row({name: 'Bill'}, crazy: {a: 1, b: 9}, cool: {c: 12, d: 19})
174
174
  row = Pet.connection.select_one(%{SELECT crazy, cool FROM pets WHERE name = 'Bill'})
175
175
  crazy = PgHstore.parse row['crazy']
176
- crazy.should == { a: '1', b: '9' }
176
+ crazy.should == { 'a' => '1', 'b' => '9' }
177
177
  cool = PgHstore.parse row['cool']
178
- cool.should == { c: '12', d: '19' }
178
+ cool.should == { 'c' => '12', 'd' => '19' }
179
179
  end
180
180
 
181
181
  it "can deletes keys from multiple hstores at once" do
@@ -184,35 +184,35 @@ EOS
184
184
  upsert.row({name: 'Bill'}, crazy: {a: 1}, cool: {5 => 9})
185
185
  row = Pet.connection.select_one(%{SELECT crazy, cool FROM pets WHERE name = 'Bill'})
186
186
  crazy = PgHstore.parse row['crazy']
187
- crazy.should == { a: '1' }
188
- cool = PgHstore.parse row['cool'], false
187
+ crazy.should == { 'a' => '1' }
188
+ cool = PgHstore.parse row['cool']
189
189
  cool.should == { '5' => '9' }
190
190
 
191
191
  # NOOP
192
192
  upsert.row({name: 'Bill'}, crazy: {}, cool: {})
193
193
  row = Pet.connection.select_one(%{SELECT crazy, cool FROM pets WHERE name = 'Bill'})
194
194
  crazy = PgHstore.parse row['crazy']
195
- crazy.should == { a: '1' }
196
- cool = PgHstore.parse row['cool'], false
195
+ crazy.should == { 'a' => '1' }
196
+ cool = PgHstore.parse row['cool']
197
197
  cool.should == { '5' => '9' }
198
198
 
199
199
  upsert.row({name: 'Bill'}, crazy: {a: nil}, cool: {13 => 17})
200
200
  row = Pet.connection.select_one(%{SELECT crazy, cool FROM pets WHERE name = 'Bill'})
201
201
  crazy = PgHstore.parse row['crazy']
202
202
  crazy.should == {}
203
- cool = PgHstore.parse row['cool'], false
203
+ cool = PgHstore.parse row['cool']
204
204
  cool.should == { '5' => '9', '13' => '17' }
205
205
 
206
206
  upsert.row({name: 'Bill'}, crazy: {a: 1, b: 5})
207
207
  row = Pet.connection.select_one(%{SELECT crazy, cool FROM pets WHERE name = 'Bill'})
208
208
  crazy = PgHstore.parse row['crazy']
209
- crazy.should == { a: '1', b: '5' }
209
+ crazy.should == { 'a' => '1', 'b' => '5' }
210
210
 
211
211
  upsert.row({name: 'Bill'}, crazy: {b: nil}, cool: {5 => nil})
212
212
  row = Pet.connection.select_one(%{SELECT crazy, cool FROM pets WHERE name = 'Bill'})
213
213
  crazy = PgHstore.parse row['crazy']
214
- crazy.should == {a: '1'}
215
- cool = PgHstore.parse row['cool'], false
214
+ crazy.should == {'a' => '1'}
215
+ cool = PgHstore.parse row['cool']
216
216
  cool.should == {'13' => '17' }
217
217
  end
218
218
 
@@ -221,12 +221,12 @@ EOS
221
221
 
222
222
  upsert.row({name: 'Bill'}, crazy: {z: 1, x: nil})
223
223
  row = Pet.connection.select_one(%{SELECT crazy FROM pets WHERE name = 'Bill'})
224
- crazy = PgHstore.parse row['crazy'], false
224
+ crazy = PgHstore.parse row['crazy']
225
225
  crazy.should == { 'z' => '1' }
226
226
 
227
227
  upsert.row({name: 'Bill'}, crazy: {a: 1})
228
228
  row = Pet.connection.select_one(%{SELECT crazy FROM pets WHERE name = 'Bill'})
229
- crazy = PgHstore.parse row['crazy'], false
229
+ crazy = PgHstore.parse row['crazy']
230
230
  crazy.should == { 'a' => '1', 'z' => '1' }
231
231
  end
232
232
 
metadata CHANGED
@@ -1,20 +1,18 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: upsert
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.1
5
- prerelease:
4
+ version: 2.0.2
6
5
  platform: ruby
7
6
  authors:
8
7
  - Seamus Abshere
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2013-07-25 00:00:00.000000000 Z
11
+ date: 2013-11-06 00:00:00.000000000 Z
13
12
  dependencies:
14
13
  - !ruby/object:Gem::Dependency
15
14
  name: rspec-core
16
15
  requirement: !ruby/object:Gem::Requirement
17
- none: false
18
16
  requirements:
19
17
  - - ! '>='
20
18
  - !ruby/object:Gem::Version
@@ -22,7 +20,6 @@ dependencies:
22
20
  type: :development
23
21
  prerelease: false
24
22
  version_requirements: !ruby/object:Gem::Requirement
25
- none: false
26
23
  requirements:
27
24
  - - ! '>='
28
25
  - !ruby/object:Gem::Version
@@ -30,7 +27,6 @@ dependencies:
30
27
  - !ruby/object:Gem::Dependency
31
28
  name: rspec-expectations
32
29
  requirement: !ruby/object:Gem::Requirement
33
- none: false
34
30
  requirements:
35
31
  - - ! '>='
36
32
  - !ruby/object:Gem::Version
@@ -38,7 +34,6 @@ dependencies:
38
34
  type: :development
39
35
  prerelease: false
40
36
  version_requirements: !ruby/object:Gem::Requirement
41
- none: false
42
37
  requirements:
43
38
  - - ! '>='
44
39
  - !ruby/object:Gem::Version
@@ -46,7 +41,6 @@ dependencies:
46
41
  - !ruby/object:Gem::Dependency
47
42
  name: rspec-mocks
48
43
  requirement: !ruby/object:Gem::Requirement
49
- none: false
50
44
  requirements:
51
45
  - - ! '>='
52
46
  - !ruby/object:Gem::Version
@@ -54,7 +48,6 @@ dependencies:
54
48
  type: :development
55
49
  prerelease: false
56
50
  version_requirements: !ruby/object:Gem::Requirement
57
- none: false
58
51
  requirements:
59
52
  - - ! '>='
60
53
  - !ruby/object:Gem::Version
@@ -62,7 +55,6 @@ dependencies:
62
55
  - !ruby/object:Gem::Dependency
63
56
  name: activerecord
64
57
  requirement: !ruby/object:Gem::Requirement
65
- none: false
66
58
  requirements:
67
59
  - - ~>
68
60
  - !ruby/object:Gem::Version
@@ -70,7 +62,6 @@ dependencies:
70
62
  type: :development
71
63
  prerelease: false
72
64
  version_requirements: !ruby/object:Gem::Requirement
73
- none: false
74
65
  requirements:
75
66
  - - ~>
76
67
  - !ruby/object:Gem::Version
@@ -78,7 +69,6 @@ dependencies:
78
69
  - !ruby/object:Gem::Dependency
79
70
  name: active_record_inline_schema
80
71
  requirement: !ruby/object:Gem::Requirement
81
- none: false
82
72
  requirements:
83
73
  - - ! '>='
84
74
  - !ruby/object:Gem::Version
@@ -86,7 +76,6 @@ dependencies:
86
76
  type: :development
87
77
  prerelease: false
88
78
  version_requirements: !ruby/object:Gem::Requirement
89
- none: false
90
79
  requirements:
91
80
  - - ! '>='
92
81
  - !ruby/object:Gem::Version
@@ -94,7 +83,6 @@ dependencies:
94
83
  - !ruby/object:Gem::Dependency
95
84
  name: faker
96
85
  requirement: !ruby/object:Gem::Requirement
97
- none: false
98
86
  requirements:
99
87
  - - ! '>='
100
88
  - !ruby/object:Gem::Version
@@ -102,7 +90,6 @@ dependencies:
102
90
  type: :development
103
91
  prerelease: false
104
92
  version_requirements: !ruby/object:Gem::Requirement
105
- none: false
106
93
  requirements:
107
94
  - - ! '>='
108
95
  - !ruby/object:Gem::Version
@@ -110,7 +97,6 @@ dependencies:
110
97
  - !ruby/object:Gem::Dependency
111
98
  name: yard
112
99
  requirement: !ruby/object:Gem::Requirement
113
- none: false
114
100
  requirements:
115
101
  - - ! '>='
116
102
  - !ruby/object:Gem::Version
@@ -118,7 +104,6 @@ dependencies:
118
104
  type: :development
119
105
  prerelease: false
120
106
  version_requirements: !ruby/object:Gem::Requirement
121
- none: false
122
107
  requirements:
123
108
  - - ! '>='
124
109
  - !ruby/object:Gem::Version
@@ -126,7 +111,6 @@ dependencies:
126
111
  - !ruby/object:Gem::Dependency
127
112
  name: activerecord-import
128
113
  requirement: !ruby/object:Gem::Requirement
129
- none: false
130
114
  requirements:
131
115
  - - ! '>='
132
116
  - !ruby/object:Gem::Version
@@ -134,7 +118,6 @@ dependencies:
134
118
  type: :development
135
119
  prerelease: false
136
120
  version_requirements: !ruby/object:Gem::Requirement
137
- none: false
138
121
  requirements:
139
122
  - - ! '>='
140
123
  - !ruby/object:Gem::Version
@@ -142,7 +125,6 @@ dependencies:
142
125
  - !ruby/object:Gem::Dependency
143
126
  name: pry
144
127
  requirement: !ruby/object:Gem::Requirement
145
- none: false
146
128
  requirements:
147
129
  - - ! '>='
148
130
  - !ruby/object:Gem::Version
@@ -150,7 +132,6 @@ dependencies:
150
132
  type: :development
151
133
  prerelease: false
152
134
  version_requirements: !ruby/object:Gem::Requirement
153
- none: false
154
135
  requirements:
155
136
  - - ! '>='
156
137
  - !ruby/object:Gem::Version
@@ -158,7 +139,6 @@ dependencies:
158
139
  - !ruby/object:Gem::Dependency
159
140
  name: pg-hstore
160
141
  requirement: !ruby/object:Gem::Requirement
161
- none: false
162
142
  requirements:
163
143
  - - ! '>='
164
144
  - !ruby/object:Gem::Version
@@ -166,7 +146,6 @@ dependencies:
166
146
  type: :development
167
147
  prerelease: false
168
148
  version_requirements: !ruby/object:Gem::Requirement
169
- none: false
170
149
  requirements:
171
150
  - - ! '>='
172
151
  - !ruby/object:Gem::Version
@@ -174,7 +153,6 @@ dependencies:
174
153
  - !ruby/object:Gem::Dependency
175
154
  name: sequel
176
155
  requirement: !ruby/object:Gem::Requirement
177
- none: false
178
156
  requirements:
179
157
  - - ! '>='
180
158
  - !ruby/object:Gem::Version
@@ -182,7 +160,6 @@ dependencies:
182
160
  type: :development
183
161
  prerelease: false
184
162
  version_requirements: !ruby/object:Gem::Requirement
185
- none: false
186
163
  requirements:
187
164
  - - ! '>='
188
165
  - !ruby/object:Gem::Version
@@ -190,7 +167,6 @@ dependencies:
190
167
  - !ruby/object:Gem::Dependency
191
168
  name: sqlite3
192
169
  requirement: !ruby/object:Gem::Requirement
193
- none: false
194
170
  requirements:
195
171
  - - ! '>='
196
172
  - !ruby/object:Gem::Version
@@ -198,7 +174,6 @@ dependencies:
198
174
  type: :development
199
175
  prerelease: false
200
176
  version_requirements: !ruby/object:Gem::Requirement
201
- none: false
202
177
  requirements:
203
178
  - - ! '>='
204
179
  - !ruby/object:Gem::Version
@@ -206,7 +181,6 @@ dependencies:
206
181
  - !ruby/object:Gem::Dependency
207
182
  name: mysql2
208
183
  requirement: !ruby/object:Gem::Requirement
209
- none: false
210
184
  requirements:
211
185
  - - ! '>='
212
186
  - !ruby/object:Gem::Version
@@ -214,7 +188,6 @@ dependencies:
214
188
  type: :development
215
189
  prerelease: false
216
190
  version_requirements: !ruby/object:Gem::Requirement
217
- none: false
218
191
  requirements:
219
192
  - - ! '>='
220
193
  - !ruby/object:Gem::Version
@@ -222,7 +195,6 @@ dependencies:
222
195
  - !ruby/object:Gem::Dependency
223
196
  name: pg
224
197
  requirement: !ruby/object:Gem::Requirement
225
- none: false
226
198
  requirements:
227
199
  - - ! '>='
228
200
  - !ruby/object:Gem::Version
@@ -230,7 +202,6 @@ dependencies:
230
202
  type: :development
231
203
  prerelease: false
232
204
  version_requirements: !ruby/object:Gem::Requirement
233
- none: false
234
205
  requirements:
235
206
  - - ! '>='
236
207
  - !ruby/object:Gem::Version
@@ -238,7 +209,6 @@ dependencies:
238
209
  - !ruby/object:Gem::Dependency
239
210
  name: redcarpet
240
211
  requirement: !ruby/object:Gem::Requirement
241
- none: false
242
212
  requirements:
243
213
  - - ! '>='
244
214
  - !ruby/object:Gem::Version
@@ -246,7 +216,6 @@ dependencies:
246
216
  type: :development
247
217
  prerelease: false
248
218
  version_requirements: !ruby/object:Gem::Requirement
249
- none: false
250
219
  requirements:
251
220
  - - ! '>='
252
221
  - !ruby/object:Gem::Version
@@ -254,7 +223,6 @@ dependencies:
254
223
  - !ruby/object:Gem::Dependency
255
224
  name: rake
256
225
  requirement: !ruby/object:Gem::Requirement
257
- none: false
258
226
  requirements:
259
227
  - - ! '>='
260
228
  - !ruby/object:Gem::Version
@@ -262,7 +230,6 @@ dependencies:
262
230
  type: :development
263
231
  prerelease: false
264
232
  version_requirements: !ruby/object:Gem::Requirement
265
- none: false
266
233
  requirements:
267
234
  - - ! '>='
268
235
  - !ruby/object:Gem::Version
@@ -333,27 +300,26 @@ files:
333
300
  - upsert.gemspec
334
301
  homepage: https://github.com/seamusabshere/upsert
335
302
  licenses: []
303
+ metadata: {}
336
304
  post_install_message:
337
305
  rdoc_options: []
338
306
  require_paths:
339
307
  - lib
340
308
  required_ruby_version: !ruby/object:Gem::Requirement
341
- none: false
342
309
  requirements:
343
310
  - - ! '>='
344
311
  - !ruby/object:Gem::Version
345
312
  version: '0'
346
313
  required_rubygems_version: !ruby/object:Gem::Requirement
347
- none: false
348
314
  requirements:
349
315
  - - ! '>='
350
316
  - !ruby/object:Gem::Version
351
317
  version: '0'
352
318
  requirements: []
353
319
  rubyforge_project:
354
- rubygems_version: 1.8.25
320
+ rubygems_version: 2.1.5
355
321
  signing_key:
356
- specification_version: 3
322
+ specification_version: 4
357
323
  summary: Make it easy to upsert on MySQL, PostgreSQL, and SQLite3. Transparently creates
358
324
  merge functions for MySQL and PostgreSQL; on SQLite3, uses INSERT OR IGNORE.
359
325
  test_files: