Methods
Public Class
Public Instance
Attributes
Public Class methods
extended(db)
Do some setup for the data structures the module uses.
[show source]
# File lib/sequel/extensions/pg_row.rb 392 def self.extended(db) 393 db.instance_exec do 394 @row_types = {} 395 @row_schema_types = {} 396 extend(@row_type_method_module = Sequel.set_temp_name(Module.new){"Sequel::Postgres::PGRow::DatabaseMethods::_RowTypeMethodModule"}) 397 add_conversion_proc(2249, PGRow::Parser.new(:converter=>PGRow::ArrayRow)) 398 if respond_to?(:register_array_type) 399 register_array_type('record', :oid=>2287, :scalar_oid=>2249) 400 end 401 end 402 end
Public Instance methods
bound_variable_arg(arg, conn)
[show source]
# File lib/sequel/extensions/pg_row.rb 405 def bound_variable_arg(arg, conn) 406 case arg 407 when ArrayRow 408 "(#{arg.map{|v| bound_variable_array(v) if v}.join(',')})" 409 when HashRow 410 arg.check_columns! 411 "(#{arg.values_at(*arg.columns).map{|v| bound_variable_array(v) if v}.join(',')})" 412 else 413 super 414 end 415 end
freeze()
Freeze the row types and row schema types to prevent adding new ones.
[show source]
# File lib/sequel/extensions/pg_row.rb 418 def freeze 419 @row_types.freeze 420 @row_schema_types.freeze 421 @row_type_method_module.freeze 422 super 423 end
register_row_type(db_type, opts=OPTS)
Register a new row type for the Database
instance. db_type should be the type symbol. This parses the PostgreSQL system tables to get information the composite type, and by default has the type return instances of a subclass of HashRow
.
The following options are supported:
:converter |
Use a custom converter for the parser. |
:typecaster |
Use a custom typecaster for the parser. |
[show source]
# File lib/sequel/extensions/pg_row.rb 434 def register_row_type(db_type, opts=OPTS) 435 procs = @conversion_procs 436 rel_oid = nil 437 array_oid = nil 438 parser_opts = {} 439 440 # Try to handle schema-qualified types. 441 type_schema, type_name = schema_and_table(db_type) 442 schema_type_string = type_name.to_s 443 444 # Get basic oid information for the composite type. 445 ds = from(:pg_type). 446 select{[pg_type[:oid], :typrelid, :typarray]}. 447 where([[:typtype, 'c'], [:typname, type_name.to_s]]) 448 if type_schema 449 ds = ds.join(:pg_namespace, [[:oid, :typnamespace], [:nspname, type_schema.to_s]]) 450 schema_type_symbol = :"pg_row_#{type_schema}__#{type_name}" 451 else 452 schema_type_symbol = :"pg_row_#{type_name}" 453 end 454 unless row = ds.first 455 raise Error, "row type #{db_type.inspect} not found in database" 456 end 457 # Manually cast to integer using to_i, because adapter may not cast oid type 458 # correctly (e.g. swift) 459 parser_opts[:oid], rel_oid, array_oid = row.values_at(:oid, :typrelid, :typarray).map(&:to_i) 460 461 # Get column names and oids for each of the members of the composite type. 462 res = from(:pg_attribute). 463 join(:pg_type, :oid=>:atttypid). 464 where(:attrelid=>rel_oid). 465 where{attnum > 0}. 466 exclude(:attisdropped). 467 order(:attnum). 468 select_map{[:attname, Sequel.case({0=>:atttypid}, pg_type[:typbasetype], pg_type[:typbasetype]).as(:atttypid)]} 469 if res.empty? 470 raise Error, "no columns for row type #{db_type.inspect} in database" 471 end 472 parser_opts[:columns] = res.map{|r| r[0].to_sym} 473 parser_opts[:column_oids] = res.map{|r| r[1].to_i} 474 475 # Using the conversion_procs, lookup converters for each member of the composite type 476 parser_opts[:column_converters] = parser_opts[:column_oids].map do |oid| 477 procs[oid] 478 end 479 480 # Setup the converter and typecaster 481 parser_opts[:converter] = opts.fetch(:converter){HashRow.subclass(db_type, parser_opts[:columns])} 482 parser_opts[:typecaster] = opts.fetch(:typecaster, parser_opts[:converter]) 483 484 parser = Parser.new(parser_opts) 485 add_conversion_proc(parser.oid, parser) 486 487 if respond_to?(:register_array_type) && array_oid && array_oid > 0 488 array_type_name = if type_schema 489 "#{type_schema}.#{type_name}" 490 else 491 type_name 492 end 493 register_array_type(array_type_name, :oid=>array_oid, :converter=>parser, :scalar_typecast=>schema_type_symbol) 494 end 495 496 @row_types[literal(db_type)] = opts.merge(:parser=>parser, :type=>db_type) 497 @row_schema_types[schema_type_string] = schema_type_symbol 498 @schema_type_classes[schema_type_symbol] = ROW_TYPE_CLASSES 499 @row_type_method_module.class_eval do 500 meth = :"typecast_value_#{schema_type_symbol}" 501 define_method(meth) do |v| 502 row_type(db_type, v) 503 end 504 private meth 505 alias_method(meth, meth) 506 end 507 508 nil 509 end
row_type(db_type, obj)
Handle typecasting of the given object to the given database type. In general, the given database type should already be registered, but if obj is an array, this will handled unregistered types.
[show source]
# File lib/sequel/extensions/pg_row.rb 514 def row_type(db_type, obj) 515 (type_hash = @row_types[literal(db_type)]) && 516 (parser = type_hash[:parser]) 517 518 case obj 519 when ArrayRow, HashRow 520 obj 521 when Array 522 if parser 523 parser.typecast(obj) 524 else 525 obj = ArrayRow.new(obj) 526 obj.db_type = db_type 527 obj 528 end 529 when Hash 530 if parser 531 parser.typecast(obj) 532 else 533 raise InvalidValue, "Database#row_type requires the #{db_type.inspect} type have a registered parser and typecaster when called with a hash" 534 end 535 else 536 raise InvalidValue, "cannot convert #{obj.inspect} to row type #{db_type.inspect}" 537 end 538 end