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 334 def initialize(source, converter=nil) 335 super(source) 336 @converter = converter 337 @stack = [[]] 338 @encoding = string.encoding 339 @recorded = String.new.force_encoding(@encoding) 340 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 344 def new_entry(include_empty=false) 345 if !@recorded.empty? || include_empty 346 entry = @recorded 347 if entry == 'NULL' && !include_empty 348 entry = nil 349 elsif @converter 350 entry = @converter.call(entry) 351 end 352 @stack.last.push(entry) 353 @recorded = String.new.force_encoding(@encoding) 354 end 355 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 359 def parse 360 raise Sequel::Error, "invalid array, empty string" if eos? 361 raise Sequel::Error, "invalid array, doesn't start with {" unless scan(/((\[\d+:\d+\])+=)?\{/) 362 363 # :nocov: 364 while !eos? 365 # :nocov: 366 char = scan(/[{}",]|[^{}",]+/) 367 if char == ',' 368 # Comma outside quoted string indicates end of current entry 369 new_entry 370 elsif char == '"' 371 raise Sequel::Error, "invalid array, opening quote with existing recorded data" unless @recorded.empty? 372 # :nocov: 373 while true 374 # :nocov: 375 char = scan(/["\\]|[^"\\]+/) 376 if char == '\\' 377 @recorded << getch 378 elsif char == '"' 379 n = peek(1) 380 raise Sequel::Error, "invalid array, closing quote not followed by comma or closing brace" unless n == ',' || n == '}' 381 break 382 else 383 @recorded << char 384 end 385 end 386 new_entry(true) 387 elsif char == '{' 388 raise Sequel::Error, "invalid array, opening brace with existing recorded data" unless @recorded.empty? 389 390 # Start of new array, add it to the stack 391 new = [] 392 @stack.last << new 393 @stack << new 394 elsif char == '}' 395 # End of current array, add current entry to the current array 396 new_entry 397 398 if @stack.length == 1 399 raise Sequel::Error, "array parsing finished without parsing entire string" unless eos? 400 401 # Top level of array, parsing should be over. 402 # Pop current array off stack and return it as result 403 return @stack.pop 404 else 405 # Nested array, pop current array off stack 406 @stack.pop 407 end 408 else 409 # Add the character to the recorded character buffer. 410 @recorded << char 411 end 412 end 413 414 raise Sequel::Error, "array parsing finished with array unclosed" 415 end