pg-hstore 1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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: