diff options
Diffstat (limited to 'activerecord')
-rw-r--r-- | activerecord/CHANGELOG | 2 | ||||
-rw-r--r-- | activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb | 30 |
2 files changed, 31 insertions, 1 deletions
diff --git a/activerecord/CHANGELOG b/activerecord/CHANGELOG index 1ca6349117..16fb14b9a5 100644 --- a/activerecord/CHANGELOG +++ b/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, diff --git a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb index 359cb067a2..ef939d747b 100644 --- a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb +++ b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb @@ -37,6 +37,7 @@ module ActiveRecord end module ConnectionAdapters + class PostgreSQLAdapter < AbstractAdapter # :nodoc: def select_all(sql, name = nil) select(sql, name) @@ -76,6 +77,14 @@ module ActiveRecord 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 @@ module ActiveRecord 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 @@ module ActiveRecord 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 |