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