Skip to content

Commit

Permalink
Fixed binary support for PostgreSQL rails#444 [alex@byzantine.no]
Browse files Browse the repository at this point in the history
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 ad63c96
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 1 deletion.
2 changes: 2 additions & 0 deletions activerecord/CHANGELOG
@@ -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,
Expand Down
Expand Up @@ -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)
Expand Down Expand Up @@ -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
Expand All @@ -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"
Expand Down Expand Up @@ -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

Expand Down

0 comments on commit ad63c96

Please sign in to comment.