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