class MySQLBinUUID::Type

Public Instance Methods

cast(value) click to toggle source

Invoked when a value that is returned from the database needs to be displayed into something readable again.

Calls superclass method
# File lib/mysql-binuuid/type.rb, line 11
def cast(value)
  if value.is_a?(MySQLBinUUID::Type::Data)
    # It could be a Data object, in which case we should add dashes to the
    # string value from there.
    add_dashes(value.to_s)
  elsif value.is_a?(String) && value.encoding == Encoding::ASCII_8BIT && strip_dashes(value).length != 32
    # We cannot unpack something that looks like a UUID, with or without
    # dashes. Not entirely sure why ActiveRecord does a weird combination of
    # cast and serialize before anything needs to be saved..
    undashed_uuid = value.unpack1('H*')
    add_dashes(undashed_uuid.to_s)
  else
    super
  end
end
serialize(value) click to toggle source

Invoked when the provided value needs to be serialized before storing it to the database.

# File lib/mysql-binuuid/type.rb, line 29
def serialize(value)
  return if value.nil?
  undashed_uuid = strip_dashes(value)

  # To avoid SQL injection, verify that it looks like a UUID. ActiveRecord
  # does not explicity escape the Binary data type. escaping is implicit as
  # the Binary data type always converts its value to a hex string.
  unless valid_undashed_uuid?(undashed_uuid)
    raise MySQLBinUUID::InvalidUUID, "#{value} is not a valid UUID"
  end

  Data.new(undashed_uuid)
end
type() click to toggle source
# File lib/mysql-binuuid/type.rb, line 5
def type
  :uuid
end

Private Instance Methods

add_dashes(uuid) click to toggle source

A UUID consists of 5 groups of characters.

8 chars - 4 chars - 4 chars - 4 chars - 12 characters

This function re-introduces the dashes since we removed them during serialization, so:

add_dashes("2b4a233152694c6e9d1e098804ab812b")
  => "2b4a2331-5269-4c6e-9d1e-098804ab812b"
# File lib/mysql-binuuid/type.rb, line 69
def add_dashes(uuid)
  return uuid if uuid =~ /\-/
  [uuid[0..7], uuid[8..11], uuid[12..15], uuid[16..19], uuid[20..-1]].join("-")
end
strip_dashes(uuid) click to toggle source

A UUID has 4 dashes is displayed with 4 dashes at the same place all the time. So they don't add anything semantically. We can safely remove them before storing to the database, and re-add them whenever we retrieved a value from the database.

strip_dashes("2b4a2331-5269-4c6e-9d1e-098804ab812b")
  => "2b4a233152694c6e9d1e098804ab812b"
# File lib/mysql-binuuid/type.rb, line 82
def strip_dashes(uuid)
  uuid.delete("-")
end
valid_undashed_uuid?(value) click to toggle source

Verify that the undashed version of a UUID only contains characters that represent a hexadecimal value.

# File lib/mysql-binuuid/type.rb, line 88
def valid_undashed_uuid?(value)
  value =~ /\A[[:xdigit:]]{32}\z/
end