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