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