0
@@ -68,72 +68,6 @@ module ActiveRecord
0
- # Escapes binary strings for bytea input to the database.
0
- def self.string_to_binary(value)
0
- if PGconn.respond_to?(:escape_bytea)
0
- self.class.module_eval do
0
- define_method(:string_to_binary) do |value|
0
- PGconn.escape_bytea(value) if value
0
- self.class.module_eval do
0
- define_method(:string_to_binary) do |value|
0
- value.each_byte { |c| result << sprintf('\\\\%03o', c) }
0
- self.class.string_to_binary(value)
0
- # Unescapes bytea output from a database to the binary string it represents.
0
- def self.binary_to_string(value)
0
- # In each case, check if the value actually is escaped PostgreSQL bytea output
0
- # or an unescaped Active Record attribute that was just written.
0
- if PGconn.respond_to?(:unescape_bytea)
0
- self.class.module_eval do
0
- define_method(:binary_to_string) do |value|
0
- PGconn.unescape_bytea(value)
0
- self.class.module_eval do
0
- define_method(:binary_to_string) do |value|
0
- i, max = 0, value.size
0
- char = value[i+1..i+3].oct
0
- self.class.binary_to_string(value)
0
# Maps PostgreSQL-specific data types to logical Rails types.
0
def simplified_type(field_type)
0
@@ -347,10 +281,78 @@ module ActiveRecord
0
# QUOTING ==================================================
0
+ # Escapes binary strings for bytea input to the database.
0
+ def escape_bytea(value)
0
+ if PGconn.respond_to?(:escape_bytea)
0
+ self.class.instance_eval do
0
+ define_method(:escape_bytea) do |value|
0
+ PGconn.escape_bytea(value) if value
0
+ self.class.instance_eval do
0
+ define_method(:escape_bytea) do |value|
0
+ value.each_byte { |c| result << sprintf('\\\\%03o', c) }
0
+ # Unescapes bytea output from a database to the binary string it represents.
0
+ # NOTE: This is NOT an inverse of escape_bytea! This is only to be used
0
+ # on escaped binary output from database drive.
0
+ def unescape_bytea(value)
0
+ # In each case, check if the value actually is escaped PostgreSQL bytea output
0
+ # or an unescaped Active Record attribute that was just written.
0
+ if PGconn.respond_to?(:unescape_bytea)
0
+ self.class.instance_eval do
0
+ define_method(:unescape_bytea) do |value|
0
+ PGconn.unescape_bytea(value)
0
+ self.class.instance_eval do
0
+ define_method(:unescape_bytea) do |value|
0
+ i, max = 0, value.size
0
+ char = value[i+1..i+3].oct
0
# Quotes PostgreSQL-specific data types for SQL input.
0
def quote(value, column = nil) #:nodoc:
0
if value.kind_of?(String) && column && column.type == :binary
0
- "#{quoted_string_prefix}'#{
column.class.string_to_binary(value)}'"
0
+ "#{quoted_string_prefix}'#{
escape_bytea(value)}'"
0
elsif value.kind_of?(String) && column && column.sql_type =~ /^xml$/
0
"xml '#{quote_string(value)}'"
0
elsif value.kind_of?(Numeric) && column && column.sql_type =~ /^money$/
0
@@ -463,11 +465,20 @@ module ActiveRecord
0
# create a 2D array representing the result set
0
def result_as_array(res) #:nodoc:
0
+ # check if we have any binary column and if they need escaping
0
+ for j in 0...res.nfields do
0
+ # unescape string passed BYTEA field (OID == 17)
0
+ unescape_col << ( res.fformat(j)==0 and res.ftype(j)==17 )
0
for i in 0...res.ntuples do
0
for j in 0...res.nfields do
0
- ary[i] << res.getvalue(i,j)
0
+ data = res.getvalue(i,j)
0
+ data = unescape_bytea(data) if unescape_col[j] and data.is_a?(String)