Permalink
Browse files

Fixed binary support for PostgreSQL #444 [alex@byzantine.no]

git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@410 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
  • Loading branch information...
dhh committed Jan 15, 2005
1 parent 2997f9c commit ad63c96ff217ac20b561fd99d91c43859657250a
View
@@ -1,5 +1,7 @@
*SVN*
+* Fixed binary support for PostgreSQL #444 [alex@byzantine.no]
+
* Added a differenciation between AssociationCollection#size and -length. Now AssociationCollection#size returns the size of the
collection by executing a SELECT COUNT(*) query if the collection hasn't been loaded and calling collection.size if it has. If
it's more likely than not that the collection does have a size larger than zero and you need to fetch that collection afterwards,
@@ -37,6 +37,7 @@ def self.postgresql_connection(config) # :nodoc:
end
module ConnectionAdapters
+
class PostgreSQLAdapter < AbstractAdapter # :nodoc:
def select_all(sql, name = nil)
select(sql, name)
@@ -76,6 +77,14 @@ def begin_db_transaction() execute "BEGIN" end
def commit_db_transaction() execute "COMMIT" end
def rollback_db_transaction() execute "ROLLBACK" end
+ def quote(value, column = nil)
+ if value.class == String && column && column.type == :binary
+ quote_bytea(value)
+ else
+ super
+ end
+ end
+
def quote_column_name(name)
return "\"#{name}\""
end
@@ -96,13 +105,31 @@ def select(sql, name = nil)
fields = res.fields
results.each do |row|
hashed_row = {}
- row.each_index { |cel_index| hashed_row[fields[cel_index]] = row[cel_index] }
+ row.each_index do |cel_index|
+ column = row[cel_index]
+ if res.type(cel_index) == 17 # type oid for bytea
+ column = unescape_bytea(column)
+ end
+ hashed_row[fields[cel_index]] = column
+ end
rows << hashed_row
end
end
return rows
end
+ def quote_bytea(s)
+ "'#{escape_bytea(s)}'"
+ end
+
+ def escape_bytea(s)
+ s.gsub(/\\/) { '\\\\\\\\' }.gsub(/[^\\]/) { |c| sprintf('\\\\%03o', c[0].to_i) }
+ end
+
+ def unescape_bytea(s)
+ s.gsub(/\\([0-9][0-9][0-9])/) { $1.oct.chr }.gsub(/\\\\/) { '\\' }
+ end
+
def split_table_schema(table_name)
schema_split = table_name.split('.')
schema_name = "public"
@@ -141,6 +168,7 @@ def type_as_string(field_type, field_length)
when 'numeric', 'real', 'money' then 'float'
when 'character varying', 'interval' then 'string'
when 'timestamp without time zone' then 'datetime'
+ when 'bytea' then 'binary'
else field_type
end

0 comments on commit ad63c96

Please sign in to comment.