Binary_to_string/string_to_binary confusion


#1

I am attempting to write a FrontBase activerecord adaptor. I’m down
to only two unit tests failing, and one of them is binary_test.rb.

I can’t figure out the logic of binary to string conversion.

Internally, I want the ‘data’ attribute to be a String object
identical to the contents of

BINARY_FIXTURE_PATH = File.dirname(FILE) + ‘/fixtures/flowers.jpg’

When it gets written to the database, it should be hex-encoded similar
to the following:

INSERT INTO binaries (“id”, “data”) VALUES(1,
X’D20A0E21390A684AC0A80116’)

only with the hex portion being much larger.

I’m having trouble implementing binary_to_string and string_to_binary.

If I implement both of them to simply return value, then the first two
asserts pass:

assert @data == bin.data, ‘Newly assigned data differs from original’
assert @data == bin.data, ‘Data differs from original after save’

but the generated SQL is invalid because it attempts to insert raw
binary into the database.

If I implement them as follows:

  def self.hex_encode(value)
    retvalue = ""
    value.each_byte do |b|
      retvalue << sprintf("%02X", b)
    end
    retvalue
  end

  def self.hex_decode(value)
    retvalue = ""
    value.scan(/../) do |h|
      c = h.hex
      retvalue << c.chr
    end
    retvalue
  end

  def self.string_to_binary(value)
    value = self.hex_decode(value)
    value
  end

  def self.binary_to_string(value)
    value = self.hex_encode(value)
    value
  end

Then the first two tests still pass, but the third pass fails:

  1. Failure:
    test_load_save(BinaryTest) [binary_test.rb:36]:
    Reloaded data differs from original.
    is not true.

It is failing because it is storing the raw X’’ data
instead of converting it back into binary.

Lookint at the code, it appears that database results pass through the
type_cast method to convert into native objects. That code shows that
:binary column types pass through binary_to_string. However, if I
implement binary_to_string to decode data fetched from the database,
then set accessors fail because for some reason they also call
binary_to_string when setting the value of data. In one case, the
source data is hex-encoded and in one case it is not. No matter how I
implement the method, it is going to break in one of the use cases.

I can’t figure out where too hook in to convert the hex-encoded result
of the raw SQL select back into a raw data string without breaking the
first two asserts.

Can anyone point me to the correct path?

Thanks