aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord
diff options
context:
space:
mode:
authorDavid Heinemeier Hansson <david@loudthinking.com>2005-01-02 15:09:03 +0000
committerDavid Heinemeier Hansson <david@loudthinking.com>2005-01-02 15:09:03 +0000
commit089ef42520968c7852c97faf07e5101685885150 (patch)
tree9a458179781134d769688b2237c615664e98a7cd /activerecord
parent959f362ac483bb12dab7d0207d973f1ebadcb033 (diff)
downloadrails-089ef42520968c7852c97faf07e5101685885150.tar.gz
rails-089ef42520968c7852c97faf07e5101685885150.tar.bz2
rails-089ef42520968c7852c97faf07e5101685885150.zip
Fixed handling of binary content in blobs and similar fields for Ruby/MySQL and SQLite #409 [xal]
git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@309 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
Diffstat (limited to 'activerecord')
-rw-r--r--activerecord/CHANGELOG2
-rwxr-xr-xactiverecord/lib/active_record/connection_adapters/abstract_adapter.rb23
-rw-r--r--activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb24
3 files changed, 45 insertions, 4 deletions
diff --git a/activerecord/CHANGELOG b/activerecord/CHANGELOG
index 4234e4cb1d..59bcb3e712 100644
--- a/activerecord/CHANGELOG
+++ b/activerecord/CHANGELOG
@@ -1,5 +1,7 @@
*SVN*
+* Fixed handling of binary content in blobs and similar fields for Ruby/MySQL and SQLite #409 [xal]
+
* Added dynamic attribute-based finders as a cleaner way of getting objects by simple queries without turning to SQL.
They work by appending the name of an attribute to <tt>find_by_</tt>, so you get finders like <tt>Person.find_by_user_name,
Payment.find_by_transaction_id</tt>. So instead of writing <tt>Person.find_first(["user_name = ?", user_name])</tt>, you just do
diff --git a/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb b/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb
index 454fe98e7f..547c98911a 100755
--- a/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb
@@ -184,6 +184,7 @@ module ActiveRecord
when :timestamp then Time
when :time then Time
when :text, :string then String
+ when :binary then String
when :boolean then Object
end
end
@@ -199,6 +200,7 @@ module ActiveRecord
when :timestamp then string_to_time(value)
when :time then string_to_dummy_time(value)
when :date then string_to_date(value)
+ when :binary then binary_to_string(value)
when :boolean then (value == "t" or value == true ? true : false)
else value
end
@@ -207,6 +209,14 @@ module ActiveRecord
def human_name
Base.human_attribute_name(@name)
end
+
+ def string_to_binary(value)
+ value
+ end
+
+ def binary_to_string(value)
+ value
+ end
private
def string_to_date(string)
@@ -229,7 +239,7 @@ module ActiveRecord
# pad the resulting array with dummy date information
time_array[0] = 2000; time_array[1] = 1; time_array[2] = 1;
Time.send(Base.default_timezone, *time_array) rescue nil
- end
+ end
def extract_limit(sql_type)
$1.to_i if sql_type =~ /\((.*)\)/
@@ -249,8 +259,10 @@ module ActiveRecord
:time
when /date/i
:date
- when /(c|b)lob/i, /text/i
+ when /clob/i, /text/i
:text
+ when /blob/i, /binary/i
+ :binary
when /char/i, /string/i
:string
when /boolean/i
@@ -323,7 +335,12 @@ module ActiveRecord
def quote(value, column = nil)
case value
- when String then "'#{quote_string(value)}'" # ' (for ruby-mode)
+ when String
+ if column && column.type == :binary
+ "'#{quote_string(column.string_to_binary(value))}'" # ' (for ruby-mode)
+ else
+ "'#{quote_string(value)}'" # ' (for ruby-mode)
+ end
when NilClass then "NULL"
when TrueClass then (column && column.type == :boolean ? "'t'" : "1")
when FalseClass then (column && column.type == :boolean ? "'f'" : "0")
diff --git a/activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb b/activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb
index 604fc960aa..4dc8d634b3 100644
--- a/activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb
@@ -25,6 +25,28 @@ module ActiveRecord
end
module ConnectionAdapters
+
+ class SQLiteColumn < Column
+
+ def string_to_binary(value)
+ value.gsub(/(\0|\%)/) do
+ case $1
+ when "\0" then "%00"
+ when "%" then "%25"
+ end
+ end
+ end
+
+ def binary_to_string(value)
+ value.gsub(/(%00|%25)/) do
+ case $1
+ when "%00" then "\0"
+ when "%25" then "%"
+ end
+ end
+ end
+
+ end
class SQLiteAdapter < AbstractAdapter # :nodoc:
def select_all(sql, name = nil)
select(sql, name)
@@ -37,7 +59,7 @@ module ActiveRecord
def columns(table_name, name = nil)
table_structure(table_name).inject([]) do |columns, field|
- columns << Column.new(field['name'], field['dflt_value'], field['type'])
+ columns << SQLiteColumn.new(field['name'], field['dflt_value'], field['type'])
columns
end
end