I'm having trouble getting typed results out of the pg gem.
require 'pg'
require_relative 'spec/fixtures/database'
client = PG.connect( DB[:pg] )
client.type_map_for_queries = PG::BasicTypeMapForQueries.new(client)
client.type_map_for_results = PG::BasicTypeMapForResults.new(client)
client.exec( %|select * from testme;| ) do |query|
query.each {|r| puts r.inspect }
end
This program gives the output:
Warning: no type cast defined for type "money" with oid 790. Please cast this type explicitly to TEXT to be safe for future changes.
Warning: no type cast defined for type "numeric" with oid 1700. Please cast this type explicitly to TEXT to be safe for future changes.
{"string"=>"thing", "logical"=>true, "cash"=>"£1.23", "reel"=>"2.34", "day"=>#<Date: 2015-12-31 ((2457388j,0s,0n),+0s,2299161j)>, "float"=>3.45}
So: booleans and floats and dates (and integers) get converted, but not numerics or the money type.
Can anyone tell me how to "cast the type explicitly", assuming that I don't want to hard-code a solution for each table?
Hijacking this thread, as after some digging I finally found a way to add a custom decoder/encoder, so posting an example below:
require 'ipaddr'
require 'pg'
class InetDecoder < PG::SimpleDecoder
def decode(string, tuple=nil, field=nil)
IPAddr.new(string)
end
end
class InetEncoder < PG::SimpleEncoder
def encode(ip_addr)
ip_addr.to_s
end
end
# 0 if for text format, can also be 1 for binary
PG::BasicTypeRegistry.register_type(0, 'inet', InetEncoder, InetDecoder)
Here's a catch all for those seeking to cast strings by default:
client = PG.connect( DB[:pg] )
map = PG::BasicTypeMapForResults.new(conn)
map.default_type_map = PG::TypeMapAllStrings.new
client.type_map_for_results = map
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With