upsert 1.1.1 → 1.1.3

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG CHANGED
@@ -1,3 +1,15 @@
1
+ 1.1.3 / 2012-12-06
2
+
3
+ * Bug fix
4
+
5
+ * Don't die/fail trying to update an HStore column that has reverted to NULL.
6
+
7
+ 1.1.2 / 2012-12-06
8
+
9
+ * Enhancements
10
+
11
+ * Support for PostgreSQL's HStore
12
+
1
13
  1.1.1 / 2012-12-03
2
14
 
3
15
  * Bug fixes
data/README.md CHANGED
@@ -208,6 +208,14 @@ java.sql.DriverManager.register_driver org.postgresql.Driver.new
208
208
  connection = java.sql.DriverManager.get_connection "jdbc:postgresql://127.0.0.1/mydatabase?user=root&password=password"
209
209
  ```
210
210
 
211
+ If you want to use HStore, make the `pg-hstore` gem available and pass a Hash in setters:
212
+
213
+ ```ruby
214
+ gem 'pg-hstore'
215
+ require 'hstore'
216
+ upsert.row({:name => 'Bill'}, :mydata => {:a => 1, :b => 2})
217
+ ```
218
+
211
219
  #### Speed
212
220
 
213
221
  From the tests (updated 9/21/12):
@@ -19,6 +19,42 @@ EOS
19
19
  end
20
20
  end
21
21
  end
22
+
23
+ HSTORE_DETECTOR = /hstore/i
24
+
25
+ def initialize(*)
26
+ super
27
+ @hstore_query = !!(sql_type =~ HSTORE_DETECTOR)
28
+ end
29
+
30
+ def hstore?
31
+ @hstore_query
32
+ end
33
+
34
+ def arg_type
35
+ if hstore?
36
+ 'text'
37
+ else
38
+ super
39
+ end
40
+ end
41
+
42
+ def to_setter_value
43
+ if hstore?
44
+ "#{quoted_setter_name}::hstore"
45
+ else
46
+ super
47
+ end
48
+ end
49
+
50
+ def to_setter
51
+ if hstore?
52
+ # http://stackoverflow.com/questions/9317971/adding-a-key-to-an-empty-hstore-column
53
+ "#{quoted_name} = COALESCE(#{quoted_name}, hstore(array[]::varchar[])) || #{to_setter_value}"
54
+ else
55
+ super
56
+ end
57
+ end
22
58
  end
23
59
  end
24
60
  end
@@ -5,6 +5,7 @@ class Upsert
5
5
  # @private
6
6
  class Java_OrgPostgresqlJdbc4_Jdbc4Connection < Connection
7
7
  include Jdbc
8
+ include Postgresql
8
9
 
9
10
  def quote_ident(k)
10
11
  DOUBLE_QUOTE + k.to_s.gsub(DOUBLE_QUOTE, '""') + DOUBLE_QUOTE
@@ -2,6 +2,8 @@ class Upsert
2
2
  class Connection
3
3
  # @private
4
4
  class PG_Connection < Connection
5
+ include Postgresql
6
+
5
7
  def execute(sql, params = nil)
6
8
  if params
7
9
  Upsert.logger.debug { %{[upsert] #{sql} with #{params.inspect}} }
@@ -0,0 +1,16 @@
1
+ class Upsert
2
+ class Connection
3
+ # @private
4
+ module Postgresql
5
+ def bind_value(v)
6
+ case v
7
+ when Hash
8
+ # you must require 'hstore' from the 'pg-hstore' gem yourself
9
+ ::HStore.dump(v)[1...-1]
10
+ else
11
+ super
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -1,3 +1,3 @@
1
1
  class Upsert
2
- VERSION = "1.1.1"
2
+ VERSION = "1.1.3"
3
3
  end
@@ -0,0 +1,39 @@
1
+ require 'spec_helper'
2
+ describe Upsert do
3
+ describe 'hstore on pg' do
4
+ it "just works" do
5
+ require 'hstore'
6
+ Pet.connection.execute 'CREATE EXTENSION HSTORE'
7
+ Pet.connection.execute "ALTER TABLE pets ADD COLUMN crazy HSTORE"
8
+ upsert = Upsert.new $conn, :pets
9
+
10
+ upsert.row({name: 'Bill'}, crazy: nil)
11
+ row = Pet.connection.select_one(%{SELECT crazy FROM pets WHERE name = 'Bill'})
12
+ row['crazy'].should == nil
13
+
14
+ upsert.row({name: 'Bill'}, crazy: {a: 1})
15
+ row = Pet.connection.select_one(%{SELECT crazy FROM pets WHERE name = 'Bill'})
16
+ crazy = HStore.parse row['crazy']
17
+ crazy.should == { a: '1' }
18
+
19
+ upsert.row({name: 'Bill'}, crazy: nil)
20
+ row = Pet.connection.select_one(%{SELECT crazy FROM pets WHERE name = 'Bill'})
21
+ row['crazy'].should == nil
22
+
23
+ upsert.row({name: 'Bill'}, crazy: {a: 1})
24
+ row = Pet.connection.select_one(%{SELECT crazy FROM pets WHERE name = 'Bill'})
25
+ crazy = HStore.parse row['crazy']
26
+ crazy.should == { a: '1' }
27
+
28
+ upsert.row({name: 'Bill'}, crazy: {whatdat: 'whodat'})
29
+ row = Pet.connection.select_one(%{SELECT crazy FROM pets WHERE name = 'Bill'})
30
+ crazy = HStore.parse row['crazy']
31
+ crazy.should == { a: '1', whatdat: 'whodat' }
32
+
33
+ upsert.row({name: 'Bill'}, crazy: {a: 2})
34
+ row = Pet.connection.select_one(%{SELECT crazy FROM pets WHERE name = 'Bill'})
35
+ crazy = HStore.parse row['crazy']
36
+ crazy.should == { a: '2', whatdat: 'whodat' }
37
+ end
38
+ end
39
+ end if ENV['DB'] == 'postgresql'
data/upsert.gemspec CHANGED
@@ -28,6 +28,7 @@ Gem::Specification.new do |gem|
28
28
  gem.add_development_dependency 'yard'
29
29
  gem.add_development_dependency 'activerecord-import'
30
30
  gem.add_development_dependency 'pry'
31
+ gem.add_development_dependency 'pg-hstore'
31
32
 
32
33
  unless RUBY_VERSION >= '1.9'
33
34
  gem.add_development_dependency 'orderedhash'
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: upsert
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.1
4
+ version: 1.1.3
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-12-03 00:00:00.000000000 Z
12
+ date: 2012-12-06 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rspec-core
@@ -155,6 +155,22 @@ dependencies:
155
155
  - - ! '>='
156
156
  - !ruby/object:Gem::Version
157
157
  version: '0'
158
+ - !ruby/object:Gem::Dependency
159
+ name: pg-hstore
160
+ requirement: !ruby/object:Gem::Requirement
161
+ none: false
162
+ requirements:
163
+ - - ! '>='
164
+ - !ruby/object:Gem::Version
165
+ version: '0'
166
+ type: :development
167
+ prerelease: false
168
+ version_requirements: !ruby/object:Gem::Requirement
169
+ none: false
170
+ requirements:
171
+ - - ! '>='
172
+ - !ruby/object:Gem::Version
173
+ version: '0'
158
174
  - !ruby/object:Gem::Dependency
159
175
  name: sqlite3
160
176
  requirement: !ruby/object:Gem::Requirement
@@ -248,6 +264,7 @@ files:
248
264
  - lib/upsert/connection/PG_Connection.rb
249
265
  - lib/upsert/connection/SQLite3_Database.rb
250
266
  - lib/upsert/connection/jdbc.rb
267
+ - lib/upsert/connection/postgresql.rb
251
268
  - lib/upsert/connection/sqlite3.rb
252
269
  - lib/upsert/merge_function.rb
253
270
  - lib/upsert/merge_function/Java_ComMysqlJdbc_JDBC4Connection.rb
@@ -266,6 +283,7 @@ files:
266
283
  - spec/correctness_spec.rb
267
284
  - spec/database_functions_spec.rb
268
285
  - spec/database_spec.rb
286
+ - spec/hstore_spec.rb
269
287
  - spec/logger_spec.rb
270
288
  - spec/misc/get_postgres_reserved_words.rb
271
289
  - spec/misc/mysql_reserved.txt
@@ -310,6 +328,7 @@ test_files:
310
328
  - spec/correctness_spec.rb
311
329
  - spec/database_functions_spec.rb
312
330
  - spec/database_spec.rb
331
+ - spec/hstore_spec.rb
313
332
  - spec/logger_spec.rb
314
333
  - spec/misc/get_postgres_reserved_words.rb
315
334
  - spec/misc/mysql_reserved.txt