active_record_hstore_serializer 0.0.3 → 0.0.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.
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = 'active_record_hstore_serializer'
3
- s.version = '0.0.3'
3
+ s.version = '0.0.4'
4
4
  s.date = '2011-11-19'
5
5
  s.summary = "Serialize attributes using HStore in ActiveRecord / Rails 3.1+"
6
6
  s.description = "Leverage Postgres HStore for awesome attribute serialization."
@@ -9,27 +9,35 @@ class String
9
9
  # Validates the hstore format. Valid formats are:
10
10
  # * An empty string
11
11
  # * A string like %("foo"=>"bar"). I'll call it a "double quoted hstore format".
12
- # * A string like %('foo'=>'bar'). I'll call it a "single quoted hstore format".
12
+ # * A string like %(foo=>bar). Postgres doesn't emit this but it does accept it as input, we should accept any input Postgres does
13
+
13
14
  def valid_hstore?
14
- return true if empty? || self == "''"
15
- # This is what comes from the database
16
- dbl_quotes_re = /"([^"]+)"=>"([^"]+)"/
17
- # TODO
18
- # This is what comes from the plugin
19
- # this is a big problem, 'cause regexes does not know how to count...
20
- # how should i very values quoted with two single quotes? using .+ sux.
21
- sngl_quotes_re = /'(.+)'=>'(.+)'/
22
- self.match(dbl_quotes_re) || self.match(sngl_quotes_re)
15
+ pair = hstore_pair
16
+ !!match(/^\s*(#{pair}\s*(,\s*#{pair})*)?\s*$/)
23
17
  end
24
18
 
25
19
  # Creates a hash from a valid double quoted hstore format, 'cause this is the format
26
20
  # that postgresql spits out.
27
21
  def from_hstore
28
- Hash[ scan(/"([^"]+)"=>"([^"]+)"/) ]
22
+ token_pairs = (scan(hstore_pair)).map { |k,v| [k,v =~ /^NULL$/i ? nil : v] }
23
+ token_pairs = token_pairs.map { |k,v|
24
+ [k,v].map { |t|
25
+ case t
26
+ when nil then t
27
+ when /^"(.*)"$/ then $1.gsub(/\\(.)/, '\1')
28
+ else t.gsub(/\\(.)/, '\1')
29
+ end
30
+ }
31
+ }
32
+ Hash[ token_pairs ]
29
33
  end
30
34
 
31
- def escape_quotes
32
- self.gsub(/'/,"''")
33
- end
35
+ private
34
36
 
37
+ def hstore_pair
38
+ quoted_string = /"[^"\\]*(?:\\.[^"\\]*)*"/
39
+ unquoted_string = /[^\s=,][^\s=,\\]*(?:\\.[^\s=,\\]*|=[^,>])*/
40
+ string = /(#{quoted_string}|#{unquoted_string})/
41
+ /#{string}\s*=>\s*#{string}/
42
+ end
35
43
  end
metadata CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 0
7
7
  - 0
8
- - 3
9
- version: 0.0.3
8
+ - 4
9
+ version: 0.0.4
10
10
  platform: ruby
11
11
  authors:
12
12
  - Cody Caughlan