class RDBI::Driver::PostgreSQL::Statement
Attributes
pg_result[RW]
stmt_name[RW]
Public Class Methods
new( query, dbh )
click to toggle source
Calls superclass method
# File lib/rdbi/driver/postgresql.rb, line 282 def initialize( query, dbh ) super( query, dbh ) @stmt_name = ('stmt_' + Time.now.to_f.to_s).tr('.', '_') ep = Epoxy.new( query ) @index_map = ep.indexed_binds query = ep.quote(Hash[@index_map.compact.zip([])]) do |x| case x when Integer "$#{x+1}" when Symbol num = @index_map.index(x) "$#{num+1}" else x end end @pg_result = dbh.pg_conn.prepare( @stmt_name, query ) # @input_type_map initialized in superclass @output_type_map = RDBI::Type.create_type_hash( RDBI::Type::Out ) @output_type_map[ :bigint ] = RDBI::Type.filterlist( RDBI::Type::Filters::STR_TO_INT ) # PostgreSQL returns timestamps with and without subseconds. # RDBI by default doesn't handle timestamps with subseconds, # so here we account for that in our PostgreSQL driver check = proc do |obj| begin if obj.include?('.') format = "%Y-%m-%d %H:%M:%S.%N %z" converted_and_back = DateTime.strptime(obj, format).strftime(format) # Strip trailing zeros in subseconds converted_and_back.gsub(/\.(\d+?)0* /, ".\\1 ") == obj.gsub(/\.(\d+?)0* /, ".\\1 ") else format = "%Y-%m-%d %H:%M:%S %z" DateTime.strptime(obj, format).strftime(format) == obj end rescue ArgumentError => e if e.message == 'invalid date' false else raise e end end end convert = proc do |obj| if obj.include?('.') DateTime.strptime(obj, "%Y-%m-%d %H:%M:%S.%N %z") else DateTime.strptime(obj, "%Y-%m-%d %H:%M:%S %z") end end @output_type_map[ :timestamp ] = RDBI::Type.filterlist( TypeLib::Filter.new(check, convert) ) @finish_block = Proc.new { @dbh.pg_conn.exec("DEALLOCATE #{@stmt_name}") @pg_result.clear } end
Public Instance Methods
new_execution( *binds )
click to toggle source
Returns an Array of things used to fill out the parameters to RDBI::Result.new
# File lib/rdbi/driver/postgresql.rb, line 354 def new_execution( *binds ) binds = RDBI::Util.index_binds(binds, @index_map) pg_result = @dbh.pg_conn.exec_prepared( @stmt_name, binds ) columns = [] column_query = (0...pg_result.num_fields).map do |x| "format_type(#{ pg_result.ftype(x) }, #{ pg_result.fmod(x) }) as col#{x}" end.join(", ") unless column_query.empty? @dbh.pg_conn.exec("select #{column_query}")[0].values.each_with_index do |type, i| c = RDBI::Column.new c.name = pg_result.fname( i ).to_sym c.type = type if c.type.start_with? 'timestamp' c.ruby_type = 'timestamp'.to_sym else c.ruby_type = c.type.to_sym end columns << c end end this_schema = RDBI::Schema.new this_schema.columns = columns [ Cursor.new(pg_result, this_schema), this_schema, @output_type_map ] end
new_modification(*binds)
click to toggle source
# File lib/rdbi/driver/postgresql.rb, line 346 def new_modification(*binds) binds = RDBI::Util.index_binds(binds, @index_map) pg_result = @dbh.pg_conn.exec_prepared( @stmt_name, binds ) return pg_result.cmd_tuples end