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.
- checksums.yaml +15 -0
- data/CHANGELOG +6 -0
- data/README.md +11 -9
- data/Rakefile +7 -1
- data/lib/upsert/column_definition.rb +5 -1
- data/lib/upsert/column_definition/mysql.rb +4 -0
- data/lib/upsert/column_definition/postgresql.rb +4 -0
- data/lib/upsert/column_definition/sqlite3.rb +4 -0
- data/lib/upsert/connection/Mysql2_Client.rb +2 -1
- data/lib/upsert/connection/PG_Connection.rb +1 -1
- data/lib/upsert/merge_function/PG_Connection.rb +3 -0
- data/lib/upsert/version.rb +1 -1
- data/spec/correctness_spec.rb +5 -2
- data/spec/hstore_spec.rb +33 -33
- metadata +5 -39
checksums.yaml
ADDED
@@ -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://
|
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
|
-
|
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
|
-
|
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
|
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
|
-
|
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
|
-
|
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)'
|
@@ -34,7 +34,8 @@ class Upsert
|
|
34
34
|
when Symbol
|
35
35
|
quote_string v.to_s
|
36
36
|
when DateTime, Time
|
37
|
-
|
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
|
data/lib/upsert/version.rb
CHANGED
data/spec/correctness_spec.rb
CHANGED
@@ -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.
|
52
|
+
Pet.count.should == 0
|
53
|
+
now = Time.now
|
53
54
|
u = Upsert.new($conn, :pets)
|
54
|
-
|
55
|
+
5.times do
|
56
|
+
u.row({gender: nil, birthday: now})
|
57
|
+
end
|
55
58
|
Pet.count.should == 1
|
56
59
|
end
|
57
60
|
|
data/spec/hstore_spec.rb
CHANGED
@@ -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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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 == {
|
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 == {
|
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 == {
|
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 == {
|
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
|
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 == {
|
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
|
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
|
176
|
+
crazy.should == { 'a' => '1', 'b' => '9' }
|
177
177
|
cool = PgHstore.parse row['cool']
|
178
|
-
cool.should == { c
|
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
|
188
|
-
cool = PgHstore.parse row['cool']
|
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
|
196
|
-
cool = PgHstore.parse row['cool']
|
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']
|
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
|
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
|
215
|
-
cool = PgHstore.parse row['cool']
|
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']
|
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']
|
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.
|
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-
|
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.
|
320
|
+
rubygems_version: 2.1.5
|
355
321
|
signing_key:
|
356
|
-
specification_version:
|
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:
|