pg-hstore 1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (3) hide show
  1. data/lib/hstore.rb +76 -0
  2. data/lib/sequel-hstore.rb +18 -0
  3. metadata +64 -0
data/lib/hstore.rb ADDED
@@ -0,0 +1,76 @@
1
+ require 'strscan'
2
+
3
+ module HStore
4
+ extend self
5
+
6
+ def parse(string)
7
+ hash = {}
8
+
9
+ # remove single quotes around literal if necessary
10
+ string = string[1..-2] if string[0] == "'" and string[-1] == "'"
11
+
12
+ scanner = StringScanner.new(string)
13
+ while !scanner.eos?
14
+ k = parse_quotable_string(scanner)
15
+ skip_key_value_delimiter(scanner)
16
+ v = parse_quotable_string(scanner)
17
+ skip_pair_delimiter(scanner)
18
+ # controversial...
19
+ # to_sym, or what?
20
+ hash[k.to_sym] = v
21
+ end
22
+
23
+ hash
24
+ end
25
+
26
+ def dump(hash)
27
+ string = hash.map do |(k,v)|
28
+ if v.nil?
29
+ # represent nil as NULL without quotes
30
+ v = "NULL"
31
+ else
32
+ # otherwise, write a double-quoted string with backslash escapes for quotes
33
+ v = to_s_escaped(v)
34
+ v = "\"#{v}\""
35
+ end
36
+
37
+ # TODO: throw an error if there is a NULL key
38
+ "\"#{to_s_escaped(k)}\" => #{v}"
39
+ end.join(", ")
40
+ "'#{string}'"
41
+ end
42
+
43
+ private
44
+
45
+ def quoted_string(scanner)
46
+ key = scanner.scan(/(\\"|[^"])*/)
47
+ key = key.gsub(/\\(.)/, '\1')
48
+ scanner.skip(/"/)
49
+ key
50
+ end
51
+
52
+ def parse_quotable_string(scanner)
53
+ if scanner.scan(/"/)
54
+ value = quoted_string(scanner)
55
+ else
56
+ value = scanner.scan(/\w+/)
57
+ value = nil if value == "NULL"
58
+ # TODO: values but not keys may be NULL
59
+ end
60
+ end
61
+
62
+ def skip_key_value_delimiter(scanner)
63
+ scanner.skip(/\s*=>\s*/)
64
+ end
65
+
66
+ def skip_pair_delimiter(scanner)
67
+ scanner.skip(/,\s*/)
68
+ end
69
+
70
+
71
+ def to_s_escaped(str)
72
+ str.to_s.gsub(/\\(?!")/) {'\\\\'}.gsub(/"/, '\"').gsub(/'/, "''")
73
+ end
74
+
75
+ end
76
+
@@ -0,0 +1,18 @@
1
+ # This is an awful monkey patch lifted from some other project. Can we improve on this somehow?
2
+ # (See github.com/couchrest/couchrest-core(?))
3
+ require 'sequel/adapters/postgres'
4
+ require_relative 'hstore/hstore'
5
+
6
+ class Hash
7
+ def to_hstore
8
+ Sequel::Postgres::HStore[self]
9
+ end
10
+
11
+ def self.===(other)
12
+ return false if self == Hash && other.is_a?(Sequel::Postgres::HStore)
13
+ super
14
+ end
15
+ end
16
+
17
+ Sequel::Postgres::PG_NAMED_TYPES[:hstore] = lambda{|s| Sequel::Postgres::HStore.new_from_string(s) }
18
+
metadata ADDED
@@ -0,0 +1,64 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: pg-hstore
3
+ version: !ruby/object:Gem::Version
4
+ version: '1.0'
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Peter van Hardenberg
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2011-11-10 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rspec
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: 2.5.0
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ version: 2.5.0
30
+ description: postgresql hstore parser/deparser
31
+ email:
32
+ - pvh@heroku.com
33
+ executables: []
34
+ extensions: []
35
+ extra_rdoc_files: []
36
+ files:
37
+ - lib/hstore.rb
38
+ - lib/sequel-hstore.rb
39
+ homepage: http://github.com/pvh/pg-hstore
40
+ licenses: []
41
+ post_install_message:
42
+ rdoc_options: []
43
+ require_paths:
44
+ - lib
45
+ required_ruby_version: !ruby/object:Gem::Requirement
46
+ none: false
47
+ requirements:
48
+ - - ! '>='
49
+ - !ruby/object:Gem::Version
50
+ version: '0'
51
+ required_rubygems_version: !ruby/object:Gem::Requirement
52
+ none: false
53
+ requirements:
54
+ - - ! '>='
55
+ - !ruby/object:Gem::Version
56
+ version: '0'
57
+ requirements: []
58
+ rubyforge_project:
59
+ rubygems_version: 1.8.24
60
+ signing_key:
61
+ specification_version: 2
62
+ summary: ''
63
+ test_files: []
64
+ has_rdoc: