Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Move unpack to deserialize #60

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 20 additions & 13 deletions lib/mysql-binuuid/type.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,19 +9,9 @@ def type
# Invoked when a value that is returned from the database needs to be
# displayed into something readable again.
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
return unless value

super(add_dashes(value.to_s)) # super will encode the value as binary (Encoding::BINARY)
end

# Invoked when the provided value needs to be serialized before storing
Expand All @@ -40,6 +30,23 @@ def serialize(value)
Data.new(undashed_uuid)
end

# Converts a value from database input to the appropriate ruby type. The
# return value of this method will be returned from
# ActiveRecord::AttributeMethods::Read#read_attribute. The default
# implementation just calls Value#cast.
#
# +value+ The raw input, as provided from the database.
def deserialize(value)
return unless value

# If the value is a binary data, convert it to a hex string, and call cast(value)
if value.is_a?(String) && value.encoding == Encoding::ASCII_8BIT
super(value.unpack1("H*"))
else
super # foward to cast(value)
end
end

# We're inheriting from the Binary type since ActiveRecord in that case
# will get the hex value. All we need to do to provide the hex value of the
# UUID, is to return the UUID without dashes. And because this inherits
Expand Down
Loading