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