Skip to content
Browse files

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
  • Loading branch information...
1 parent 959f362 commit 089ef42520968c7852c97faf07e5101685885150 @dhh dhh committed
View
2 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
View
23 activerecord/lib/active_record/connection_adapters/abstract_adapter.rb
@@ -184,6 +184,7 @@ def klass
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 @@ def type_cast(value)
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 @@ def type_cast(value)
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 @@ def string_to_dummy_time(string)
# 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 @@ def simplified_type(field_type)
: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 @@ def rollback_db_transaction() end
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")
View
24 activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb
@@ -25,6 +25,28 @@ def self.sqlite_connection(config) # :nodoc:
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 @@ def select_one(sql, name = nil)
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

0 comments on commit 089ef42

Please sign in to comment.
Something went wrong with that request. Please try again.