Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
Peter van Hardenberg committed Jul 8, 2011
1 parent 13df172 commit 5718c87
Show file tree
Hide file tree
Showing 2 changed files with 74 additions and 6 deletions.
9 changes: 7 additions & 2 deletions lib/hstore/hstore.rb
Expand Up @@ -2,7 +2,7 @@

class Sequel::Postgres::HStore < Hash
def self.quoted_string(scanner)
key = scanner.scan(/(\\"|[^"])*/).gsub("\\", "")
key = scanner.scan(/(\\"|[^"])*/).gsub("\\\\", "\\")
scanner.skip(/"/)
key
end
Expand All @@ -26,6 +26,10 @@ def self.skip_pair_delimiter(scanner)

def self.new_from_string(string)
hash = {}

# remove single quotes around literal if necessary
string = string[1..-2] if string[0] == "'" and string[-1] == "'"

scanner = StringScanner.new(string)
while !scanner.eos?
k = parse_quotable_string(scanner)
Expand All @@ -44,7 +48,8 @@ def initialize(hash)
end

def to_s_escaped(str)
str.to_s.gsub(/"/, '\"').gsub(/'/, "''")
puts str
str.to_s.gsub(/\\(?!")/) {'\\\\'}.gsub(/"/, '\"').gsub(/'/, "''").tap {|s| puts s}
end

def sql_literal(dataset)
Expand Down
71 changes: 67 additions & 4 deletions test.rb
@@ -1,7 +1,37 @@
require 'sequel'
require './lib/sequel-hstore'

db = Sequel.connect(ENV["TEST_URL"])

require 'logger'
#db.logger = Logger.new($stdout)

db.create_table! :hstore_tests do
column :hstore, :hstore
end

describe "hstores in the database" do
before do
db[:hstore_tests].delete
@h = {:a => "b", :foo => "bar"}.to_hstore
end

it "should be able to store an hstore" do
db[:hstore_tests].insert(@h)
end

it "should be able to round-trip an hstore" do
db[:hstore_tests].insert(@h)
db[:hstore_tests].first[:hstore].should == @h
end

it "should be able to round-trip an hstore with backslashes" do
h = @h.merge(:slasher => 'oh \$ hell')
db[:hstore_tests].insert(h)
db[:hstore_tests].first[:hstore].should == h
end
end

describe "hstores from hashes" do
before do
@h = {:a => "b", :foo => "bar"}.to_hstore
Expand All @@ -17,7 +47,7 @@
end

it "should translate into a sequel literal" do
db[:resources].literal(@h).should == '\'"a" => "b", "foo" => "bar"\''
db[:hstore_tests].literal(@h).should == '\'"a" => "b", "foo" => "bar"\''
end
end

Expand All @@ -37,17 +67,22 @@

it "should store an empty string" do
empty = {:nothing => ""}.to_hstore
db[:resources].literal(empty).should == '\'"nothing" => ""\''
db[:hstore_tests].literal(empty).should == '\'"nothing" => ""\''
end

it "should support single quotes in strings" do
empty = {:journey => "don't stop believin'"}.to_hstore
db[:resources].literal(empty).should == %q{'"journey" => "don''t stop believin''"'}
db[:hstore_tests].literal(empty).should == %q{'"journey" => "don''t stop believin''"'}
end

it "should support double quotes in strings" do
empty = {:journey => 'He said he was "ready"'}.to_hstore
db[:resources].literal(empty).should == %q{'"journey" => "He said he was \"ready\""'}
db[:hstore_tests].literal(empty).should == %q{'"journey" => "He said he was \"ready\""'}
end

it "should escape \ garbage in strings" do
empty = {:line_noise => %q[perl -p -e 's/\$\{([^}]+)\}/]}.to_hstore
db[:hstore_tests].literal(empty).should == %q['"line_noise" => "perl -p -e ''s/\\\\$\\\\{([^}]+)\\\\}/"']
end

it "should parse an empty string" do
Expand All @@ -57,5 +92,33 @@
empty[:ip].should == ""
empty[:ip].should_not == nil
end

it "should be able to parse its own output" do
hstore = {:journey => 'He said he was ready'}.to_hstore
literal = db[:hstore_tests].literal(hstore)
parsed = Sequel::Postgres::HStore.new_from_string(literal)
parsed.should == hstore
end

it "should be able to parse hstore strings without ''" do
hstore = {:journey => 'He said he was ready'}.to_hstore
literal = db[:hstore_tests].literal(hstore)
parsed = Sequel::Postgres::HStore.new_from_string(literal[1..-2])
parsed.should == hstore
end

it "should be stable over iteration" do
hstore = {:journey => 'He said he was "ready"'}.to_hstore
literal = db[:hstore_tests].literal(hstore)

original = literal

10.times do
parsed = Sequel::Postgres::HStore.new_from_string(literal)
literal = db[:hstore_tests].literal(parsed)
parsed.should == hstore
literal.should == original
end
end
end

0 comments on commit 5718c87

Please sign in to comment.