Permalink
Browse files

fixed conflicts merging @justintv patch

  • Loading branch information...
2 parents 053ea4c + d125183 commit 41b6ae312dd6059d3fc674dd5018113809099c9e @diogob committed Sep 14, 2012
Showing with 41 additions and 15 deletions.
  1. +24 −14 lib/activerecord-postgres-hstore/hash.rb
  2. +17 −1 spec/activerecord-postgres-hstore_spec.rb
@@ -1,24 +1,34 @@
class Hash
+ HSTORE_ESCAPED = /[,\s=>\\]/
+
+ # Escapes values such that they will work in an hstore string
+ def hstore_escape(str)
+ if str.nil?
+ return 'NULL'
+ end
+
+ str = str.to_s.dup
+ # backslash is an escape character for strings, and an escape character for gsub, so you need 6 backslashes to get 2 in the output.
+ # see http://stackoverflow.com/questions/1542214/weird-backslash-substitution-in-ruby for the gory details
+ str.gsub!(/\\/, '\\\\\\')
+ # escape backslashes before injecting more backslashes
+ str.gsub!(/"/, '\"')
+
+ if str =~ HSTORE_ESCAPED or str.empty?
+ str = '"%s"' % str
+ end
+
+ return str
+ end
# Generates an hstore string format. This is the format used
# to insert or update stuff in the database.
def to_hstore
return "" if empty?
- map { |idx, val|
- iv = [idx,val].map { |_|
- e = _.to_s.gsub(/"/, '\"')
- if _.nil?
- 'NULL'
- elsif e =~ /[,\s=>]/ || e.blank?
- '"%s"' % e
- else
- e
- end
- }
-
- "%s=>%s" % iv
- } * ","
+ map do |idx, val|
+ "%s=>%s" % [hstore_escape(idx), hstore_escape(val)]
+ end * ","
end
# If the method from_hstore is called in a Hash, it just returns self.
@@ -63,13 +63,29 @@
end
it "should quote keys and values correctly with combinations of single and double quotes" do
- { %q("a') => %q(b "a' b) }.to_hstore.should eq(%q(\"a'=>"b \"a' b"))
+ { %q("a') => %q(b "a' b) }.to_hstore.should eq(%q("\"a'"=>"b \"a' b"))
end
it "should unquote keys and values correctly with combinations of single and double quotes" do
%q("\"a'"=>"b \"a' b").from_hstore.should eq({%q("a') => %q(b "a' b)})
end
+ it "should quote keys and values correctly with backslashes" do
+ { %q(\\) => %q(\\) }.to_hstore.should eq(%q("\\\\"=>"\\\\"))
+ end
+
+ it "should unquote keys and values correctly with backslashes" do
+ %q("\\\\"=>"\\\\").from_hstore.should eq({ %q(\\) => %q(\\) })
+ end
+
+ it "should quote keys and values correctly with combinations of backslashes and quotes" do
+ { %q(' \\ ") => %q(" \\ ') }.to_hstore.should eq(%q("' \\\\ \""=>"\" \\\\ '"))
+ end
+
+ it "should unquote keys and values correctly with combinations of backslashes and quotes" do
+ %q("' \\\\ \""=>"\" \\\\ '").from_hstore.should eq({ %q(' \\ ") => %q(" \\ ') })
+ end
+
it "should convert empty hash" do
{}.to_hstore.should eq("")
end

0 comments on commit 41b6ae3

Please sign in to comment.