@@ -200,14 +200,20 @@ def string_to_time(value)
200200 end
201201 end
202202
203- # These methods will only allow the adapter to insert binary data with a length of 7K or less
204- # because of a SQL Server statement length policy.
203+ # To insert into a SQL server binary column, the value must be
204+ # converted to hex characters and prepended with 0x
205+ # Example: INSERT into varbinarytable values (0x0)
206+ # See the output of the stored procedure: 'exec sp_datatype_info'
207+ # and note the literal prefix value of 0x for binary types
205208 def string_to_binary ( value )
206- Base64 . encode64 ( value )
209+ "0x #{ value . unpack ( "H*" ) [ 0 ] } "
207210 end
208211
209212 def binary_to_string ( value )
210- Base64 . decode64 ( value )
213+ # Check if the value actually is hex output from the database
214+ # or an Active Record attribute that was just written. If hex, pack the hex
215+ # characters into a string, otherwise return the value
216+ value =~ /[^[:xdigit:]]/ ? value : [ value ] . pack ( 'H*' )
211217 end
212218
213219 protected
@@ -278,6 +284,8 @@ def initialize(connection, logger, connection_options=nil)
278284 def native_database_types
279285 # support for varchar(max) and varbinary(max) for text and binary cols if our version is 9 (2005)
280286 txt = @database_version_major >= 9 ? "varchar(max)" : "text"
287+
288+ # TODO: Need to verify image column works correctly with 2000 if string_to_binary stores a hex string
281289 bin = @database_version_major >= 9 ? "varbinary(max)" : "image"
282290 {
283291 :primary_key => "int NOT NULL IDENTITY(1, 1) PRIMARY KEY" ,
@@ -491,6 +499,13 @@ def quote(value, column = nil)
491499 case value
492500 when TrueClass then '1'
493501 when FalseClass then '0'
502+
503+ when String , ActiveSupport ::Multibyte ::Chars
504+ value = value . to_s
505+
506+ # for binary columns, don't quote the result of the string to binary
507+ return column . class . string_to_binary ( value ) if column && column . type == :binary && column . class . respond_to? ( :string_to_binary )
508+ super
494509 else
495510 if value . acts_like? ( :time )
496511 "'#{ value . strftime ( "%Y%m%d %H:%M:%S" ) } '"
0 commit comments