aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord
diff options
context:
space:
mode:
authorJeremy Kemper <jeremy@bitsweat.net>2005-09-26 20:29:01 +0000
committerJeremy Kemper <jeremy@bitsweat.net>2005-09-26 20:29:01 +0000
commita5e2f6cd28710e4a81e850a77d5d0833cb1379de (patch)
tree9eb5a26b5decc6718aa1affe07e5dc3faa7c2abf /activerecord
parent79a535ecd7baaa2aa7a87435f95c6ef93b038ced (diff)
downloadrails-a5e2f6cd28710e4a81e850a77d5d0833cb1379de.tar.gz
rails-a5e2f6cd28710e4a81e850a77d5d0833cb1379de.tar.bz2
rails-a5e2f6cd28710e4a81e850a77d5d0833cb1379de.zip
r3590@asus: jeremy | 2005-09-26 17:00:53 -0700
Correct and optimize PostgreSQL bytea escaping. This is a blend of four patches, each providing a bit to the solution. git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@2347 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
Diffstat (limited to 'activerecord')
-rw-r--r--activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb50
1 files changed, 43 insertions, 7 deletions
diff --git a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
index 254b1a04a8..037f5f6869 100644
--- a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
@@ -79,7 +79,7 @@ module ActiveRecord
def quote(value, column = nil)
if value.class == String && column && column.type == :binary
- quote_bytea(value)
+ "'#{escape_bytea(value)}'"
else
super
end
@@ -266,16 +266,52 @@ module ActiveRecord
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) } unless s.nil?
+ if PGconn.respond_to? :escape_bytea
+ self.class.send(:define_method, :escape_bytea) do |s|
+ PGconn.escape_bytea(s) if s
+ end
+ else
+ self.class.send(:define_method, :escape_bytea) do |s|
+ if s
+ result = ''
+ s.each_byte { |c| result << sprintf('\\\\%03o', c) }
+ result
+ end
+ end
+ end
+ escape_bytea(s)
end
def unescape_bytea(s)
- s.gsub(/\\([0-9][0-9][0-9])/) { $1.oct.chr }.gsub(/\\\\/) { '\\' } unless s.nil?
+ if PGconn.respond_to? :unescape_bytea
+ self.class.send(:define_method, :unescape_bytea) do |s|
+ PGconn.unescape_bytea(s) if s
+ end
+ else
+ self.class.send(:define_method, :unescape_bytea) do |s|
+ if s
+ result = ''
+ i, max = 0, s.size
+ while i < max
+ char = s[i]
+ if char == ?\\
+ if s[i+1] == ?\\
+ char = ?\\
+ i += 1
+ else
+ char = s[i+1..i+3].oct
+ i += 3
+ end
+ end
+ result << char
+ i += 1
+ end
+ result
+ end
+ end
+ end
+ unescape_bytea(s)
end
# Query a table's column names, default values, and types.