Skip to content
This repository has been archived by the owner on Sep 21, 2020. It is now read-only.

Commit

Permalink
fixed conflicts merging @justintv patch
Browse files Browse the repository at this point in the history
  • Loading branch information
diogob committed Sep 14, 2012
2 parents 053ea4c + d125183 commit 41b6ae3
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 15 deletions.
38 changes: 24 additions & 14 deletions lib/activerecord-postgres-hstore/hash.rb
Original file line number Diff line number Diff line change
@@ -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.
Expand Down
18 changes: 17 additions & 1 deletion spec/activerecord-postgres-hstore_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit 41b6ae3

Please sign in to comment.