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