class Sequel::Postgres::PGArray::Parser
PostgreSQL array parser that handles PostgreSQL array output format. Note that does not handle all forms out input that PostgreSQL will accept, and it will not raise an error for all forms of invalid input.
Public Class Methods
new(source, converter=nil)
click to toggle source
Set the source for the input, and any converter callable to call with objects to be created. For nested parsers the source may contain text after the end current parse, which will be ignored.
Calls superclass method
# File lib/sequel/extensions/pg_array.rb 311 def initialize(source, converter=nil) 312 super(source) 313 @converter = converter 314 @stack = [[]] 315 @encoding = string.encoding 316 @recorded = String.new.force_encoding(@encoding) 317 end
Public Instance Methods
new_entry(include_empty=false)
click to toggle source
Take the buffer of recorded characters and add it to the array of entries, and use a new buffer for recorded characters.
# File lib/sequel/extensions/pg_array.rb 321 def new_entry(include_empty=false) 322 if !@recorded.empty? || include_empty 323 entry = @recorded 324 if entry == 'NULL' && !include_empty 325 entry = nil 326 elsif @converter 327 entry = @converter.call(entry) 328 end 329 @stack.last.push(entry) 330 @recorded = String.new.force_encoding(@encoding) 331 end 332 end
parse()
click to toggle source
Parse the input character by character, returning an array of parsed (and potentially converted) objects.
# File lib/sequel/extensions/pg_array.rb 336 def parse 337 raise Sequel::Error, "invalid array, empty string" if eos? 338 raise Sequel::Error, "invalid array, doesn't start with {" unless scan(/((\[\d+:\d+\])+=)?\{/) 339 340 while !eos? 341 char = scan(/[{}",]|[^{}",]+/) 342 if char == ',' 343 # Comma outside quoted string indicates end of current entry 344 new_entry 345 elsif char == '"' 346 raise Sequel::Error, "invalid array, opening quote with existing recorded data" unless @recorded.empty? 347 while true 348 char = scan(/["\\]|[^"\\]+/) 349 if char == '\\' 350 @recorded << getch 351 elsif char == '"' 352 n = peek(1) 353 raise Sequel::Error, "invalid array, closing quote not followed by comma or closing brace" unless n == ',' || n == '}' 354 break 355 else 356 @recorded << char 357 end 358 end 359 new_entry(true) 360 elsif char == '{' 361 raise Sequel::Error, "invalid array, opening brace with existing recorded data" unless @recorded.empty? 362 363 # Start of new array, add it to the stack 364 new = [] 365 @stack.last << new 366 @stack << new 367 elsif char == '}' 368 # End of current array, add current entry to the current array 369 new_entry 370 371 if @stack.length == 1 372 raise Sequel::Error, "array parsing finished without parsing entire string" unless eos? 373 374 # Top level of array, parsing should be over. 375 # Pop current array off stack and return it as result 376 return @stack.pop 377 else 378 # Nested array, pop current array off stack 379 @stack.pop 380 end 381 else 382 # Add the character to the recorded character buffer. 383 @recorded << char 384 end 385 end 386 387 raise Sequel::Error, "array parsing finished with array unclosed" 388 end