pg-hstore 1.1.3 → 1.1.4
Sign up to get free protection for your applications and to get access to all the features.
- 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:
|