From a315e6b68aecec2af7276db2a82fef9e758f987f Mon Sep 17 00:00:00 2001 From: Carl Douglas Date: Sat, 3 Jul 2010 19:30:59 +1000 Subject: [PATCH] Based on the infomation on literals at: http://www.sqlite.org/lang_expr.html We can write a blob literal using hexadecimal prefixed with an X. There exist examples of binary data that are corrupted by the current string_to_binary and binary_to_string methods. --- .../connection_adapters/sqlite_adapter.rb | 29 ++++++------------- activerecord/test/cases/binary_test.rb | 4 +++ 2 files changed, 13 insertions(+), 20 deletions(-) diff --git a/activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb b/activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb index 0396f34..1a77a94 100644 --- a/activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb +++ b/activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb @@ -53,27 +53,7 @@ module ActiveRecord module ConnectionAdapters #:nodoc: class SQLiteColumn < Column #:nodoc: - class << self - def string_to_binary(value) - value = value.dup.force_encoding(Encoding::BINARY) if value.respond_to?(:force_encoding) - value.gsub(/\0|\%/n) do |b| - case b - when "\0" then "%00" - when "%" then "%25" - end - end - end - def binary_to_string(value) - value = value.dup.force_encoding(Encoding::BINARY) if value.respond_to?(:force_encoding) - value.gsub(/%00|%25/n) do |b| - case b - when "%00" then "\0" - when "%25" then "%" - end - end - end - end end # The SQLite adapter works with both the 2.x and 3.x series of SQLite with the sqlite-ruby drivers (available both as gems and @@ -156,6 +136,15 @@ module ActiveRecord # QUOTING ================================================== + + def quote(value, column = nil) + if value.kind_of?(String) && column && column.type == :binary + s = value.unpack("H*")[0] + "X'#{s}'" + else + super + end + end def quote_string(s) #:nodoc: @connection.class.quote(s) diff --git a/activerecord/test/cases/binary_test.rb b/activerecord/test/cases/binary_test.rb index 8545ba9..3bd3f47 100644 --- a/activerecord/test/cases/binary_test.rb +++ b/activerecord/test/cases/binary_test.rb @@ -12,6 +12,10 @@ unless current_adapter?(:SybaseAdapter, :DB2Adapter, :FirebirdAdapter) def test_load_save Binary.delete_all + data = "%00" + bin = Binary.new(:data => data) + assert_equal data, bin.data, "Could not store %00" + FIXTURES.each do |filename| data = File.read(ASSETS_ROOT + "/#{filename}") data.force_encoding('ASCII-8BIT') if data.respond_to?(:force_encoding) -- 1.7.1