Method: Sequel::Postgres::PGRange::Parser#call

Defined in:
lib/sequel/extensions/pg_range.rb

#call(string) ⇒ Object

Parse the range type input string into a PGRange value.

Raises:

  • (InvalidValue)
[View source]

91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
# File 'lib/sequel/extensions/pg_range.rb', line 91

def call(string)
  if string == 'empty'
    return PGRange.empty(db_type)
  end

  raise(InvalidValue, "invalid or unhandled range format: #{string.inspect}") unless matches = /\A(\[|\()("((?:\\"|[^"])*)"|[^"]*),("((?:\\"|[^"])*)"|[^"]*)(\]|\))\z/.match(string)

  exclude_begin = matches[1] == '('
  exclude_end = matches[6] == ')'

  # If the input is quoted, it needs to be unescaped.  Also, quoted input isn't
  # checked for emptiness, since the empty quoted string is considered an 
  # element that happens to be the empty string, while an unquoted empty string
  # is considered unbounded.
  #
  # While PostgreSQL allows pure escaping for input (without quoting), it appears
  # to always use the quoted output form when characters need to be escaped, so
  # there isn't a need to unescape unquoted output.
  if beg = matches[3]
    beg.gsub!(/\\(.)/, '\1')
  else
    beg = matches[2] unless matches[2].empty?
  end
  if en = matches[5]
    en.gsub!(/\\(.)/, '\1')
  else
    en = matches[4] unless matches[4].empty?
  end

  if c = converter
    beg = c.call(beg) if beg
    en = c.call(en) if en
  end

  PGRange.new(beg, en, :exclude_begin=>exclude_begin, :exclude_end=>exclude_end, :db_type=>db_type)
end