pg-hstore 1.1.3 → 1.1.4
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.
- data/lib/pg_hstore.rb +46 -59
- metadata +6 -5
data/lib/pg_hstore.rb
CHANGED
@@ -1,94 +1,81 @@
|
|
1
|
-
require 'strscan'
|
2
|
-
|
3
1
|
module PgHstore
|
4
2
|
SINGLE_QUOTE = "'"
|
5
3
|
DOUBLE_QUOTE = '"'
|
6
4
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
k =
|
18
|
-
|
19
|
-
v =
|
20
|
-
|
21
|
-
|
22
|
-
# to_sym, or what?
|
23
|
-
hash[k.to_sym] = v
|
5
|
+
QUOTED_LITERAL = /"[^"\\]*(?:\\.[^"\\]*)*"/
|
6
|
+
UNQUOTED_LITERAL = /[^\s=,][^\s=,\\]*(?:\\.[^\s=,\\]*|=[^,>])*/
|
7
|
+
LITERAL = /(#{QUOTED_LITERAL}|#{UNQUOTED_LITERAL})/
|
8
|
+
PAIR = /#{LITERAL}\s*=>\s*#{LITERAL}/
|
9
|
+
NULL = /\ANULL\z/i
|
10
|
+
# set symbolize_keys = false if you want string keys
|
11
|
+
# thanks to https://github.com/engageis/activerecord-postgres-hstore for regexps!
|
12
|
+
def PgHstore.load(hstore, symbolize_keys = true)
|
13
|
+
hstore = unquote hstore, SINGLE_QUOTE
|
14
|
+
hstore.scan(PAIR).inject({}) do |memo, (k, v)|
|
15
|
+
k = unescape unquote(k, DOUBLE_QUOTE)
|
16
|
+
k = k.to_sym if symbolize_keys
|
17
|
+
v = (v =~ NULL) ? nil : unescape(unquote(v, DOUBLE_QUOTE))
|
18
|
+
memo[k] = v
|
19
|
+
memo
|
24
20
|
end
|
25
|
-
|
26
|
-
hash
|
27
21
|
end
|
28
22
|
|
29
23
|
# set for_parameter = true if you're using the output for a bind variable
|
30
|
-
def dump(hash, for_parameter = false)
|
31
|
-
|
24
|
+
def PgHstore.dump(hash, for_parameter = false)
|
25
|
+
memo = hash.map do |k, v|
|
32
26
|
if v.nil?
|
33
|
-
# represent nil as NULL without quotes
|
34
27
|
v = "NULL"
|
35
28
|
else
|
36
|
-
v =
|
29
|
+
v = escape v
|
37
30
|
unless for_parameter
|
38
|
-
v =
|
31
|
+
v = escape_single_quotes v
|
39
32
|
end
|
40
|
-
# otherwise, write a double-quoted string with backslash escapes for quotes
|
41
33
|
v = DOUBLE_QUOTE + v + DOUBLE_QUOTE
|
42
34
|
end
|
43
|
-
k =
|
35
|
+
k = escape k
|
44
36
|
unless for_parameter
|
45
|
-
k =
|
37
|
+
k = escape_single_quotes k
|
46
38
|
end
|
47
39
|
k = DOUBLE_QUOTE + k + DOUBLE_QUOTE
|
48
|
-
|
49
|
-
# TODO: throw an error if there is a NULL key
|
50
40
|
[k, v].join ' => '
|
51
|
-
end.join(
|
41
|
+
end.join(', ')
|
52
42
|
if for_parameter
|
53
|
-
|
43
|
+
memo
|
54
44
|
else
|
55
|
-
SINGLE_QUOTE +
|
45
|
+
SINGLE_QUOTE + memo + SINGLE_QUOTE
|
56
46
|
end
|
57
47
|
end
|
58
48
|
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
key = scanner.scan(/(\\"|[^"])*/)
|
63
|
-
key = key.gsub(/\\(.)/, '\1')
|
64
|
-
scanner.skip(/"/)
|
65
|
-
key
|
49
|
+
class << self
|
50
|
+
# deprecated; use PgHstore.load
|
51
|
+
alias parse load
|
66
52
|
end
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
53
|
+
|
54
|
+
private
|
55
|
+
|
56
|
+
def PgHstore.unquote(string, quote_char)
|
57
|
+
if string.start_with? quote_char
|
58
|
+
string[1..-2]
|
71
59
|
else
|
72
|
-
|
73
|
-
value = nil if value == "NULL"
|
74
|
-
# TODO: values but not keys may be NULL
|
60
|
+
string
|
75
61
|
end
|
76
62
|
end
|
77
63
|
|
78
|
-
|
79
|
-
|
64
|
+
ESCAPED_CHAR = /\\(.)/
|
65
|
+
def PgHstore.unescape(literal)
|
66
|
+
literal.gsub(ESCAPED_CHAR, '\1').gsub ESCAPED_SINGLE_QUOTE, SINGLE_QUOTE
|
80
67
|
end
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
str.to_s.gsub DOUBLE_QUOTE, '\"'
|
68
|
+
|
69
|
+
NON_ESCAPE_SLASH = '\\'
|
70
|
+
ESCAPED_SLASH = '\\\\'
|
71
|
+
ESCAPED_DOUBLE_QUOTE = '\"'
|
72
|
+
def PgHstore.escape(string)
|
73
|
+
string.to_s.gsub(NON_ESCAPE_SLASH) {ESCAPED_SLASH}.gsub DOUBLE_QUOTE, ESCAPED_DOUBLE_QUOTE
|
88
74
|
end
|
89
75
|
|
90
|
-
|
91
|
-
|
76
|
+
ESCAPED_SINGLE_QUOTE = "''"
|
77
|
+
def PgHstore.escape_single_quotes(literal)
|
78
|
+
literal.to_s.gsub SINGLE_QUOTE, ESCAPED_SINGLE_QUOTE
|
92
79
|
end
|
93
80
|
|
94
81
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pg-hstore
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.1.
|
4
|
+
version: 1.1.4
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2013-
|
13
|
+
date: 2013-02-07 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: rspec
|
@@ -28,7 +28,8 @@ dependencies:
|
|
28
28
|
- - ~>
|
29
29
|
- !ruby/object:Gem::Version
|
30
30
|
version: 2.5.0
|
31
|
-
description: postgresql hstore parser/deparser - provides PgHstore.dump and PgHstore.
|
31
|
+
description: postgresql hstore parser/deparser - provides PgHstore.dump and PgHstore.load
|
32
|
+
(aka parse)
|
32
33
|
email:
|
33
34
|
- pvh@heroku.com
|
34
35
|
- seamus@abshere.net
|
@@ -57,9 +58,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
57
58
|
version: '0'
|
58
59
|
requirements: []
|
59
60
|
rubyforge_project:
|
60
|
-
rubygems_version: 1.8.
|
61
|
+
rubygems_version: 1.8.25
|
61
62
|
signing_key:
|
62
|
-
specification_version:
|
63
|
+
specification_version: 3
|
63
64
|
summary: ''
|
64
65
|
test_files: []
|
65
66
|
has_rdoc:
|