Use a custom class for Uuid values
This commit is contained in:
committed by
Mike Dalessio
parent
f4729577b6
commit
f6ec9bbeea
@@ -10,7 +10,7 @@ ActiveSupport.on_load(:active_record) do
|
|||||||
end
|
end
|
||||||
|
|
||||||
def quote(value)
|
def quote(value)
|
||||||
if value.is_a?(String) && value.encoding == Encoding::BINARY && value.bytesize == 16
|
if value.is_a?(ActiveRecord::Type::UuidValue)
|
||||||
# Convert binary UUIDs to hex literals to avoid encoding conflicts in SQL strings
|
# Convert binary UUIDs to hex literals to avoid encoding conflicts in SQL strings
|
||||||
"X'#{value.unpack1('H*')}'"
|
"X'#{value.unpack1('H*')}'"
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -1,6 +1,30 @@
|
|||||||
# Custom UUID attribute type for MySQL binary storage with base36 string representation
|
# Custom UUID attribute type for MySQL binary storage with base36 string representation
|
||||||
module ActiveRecord
|
module ActiveRecord
|
||||||
module Type
|
module Type
|
||||||
|
# Wrapper class to distinguish UUID binary values from regular binary strings
|
||||||
|
class UuidValue
|
||||||
|
def initialize(binary_string)
|
||||||
|
@value = binary_string
|
||||||
|
end
|
||||||
|
|
||||||
|
def to_s
|
||||||
|
@value
|
||||||
|
end
|
||||||
|
|
||||||
|
# Delegate methods needed for SQL quoting
|
||||||
|
def unpack1(format)
|
||||||
|
@value.unpack1(format)
|
||||||
|
end
|
||||||
|
|
||||||
|
def bytesize
|
||||||
|
@value.bytesize
|
||||||
|
end
|
||||||
|
|
||||||
|
def encoding
|
||||||
|
@value.encoding
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
class Uuid < Binary
|
class Uuid < Binary
|
||||||
BASE36_LENGTH = 25 # 36^25 > 2^128
|
BASE36_LENGTH = 25 # 36^25 > 2^128
|
||||||
|
|
||||||
@@ -16,6 +40,7 @@ module ActiveRecord
|
|||||||
hex = value.to_s.to_i(36).to_s(16).rjust(32, "0")
|
hex = value.to_s.to_i(36).to_s(16).rjust(32, "0")
|
||||||
binary = hex.scan(/../).map(&:hex).pack("C*")
|
binary = hex.scan(/../).map(&:hex).pack("C*")
|
||||||
binary.force_encoding(Encoding::BINARY)
|
binary.force_encoding(Encoding::BINARY)
|
||||||
|
UuidValue.new(binary)
|
||||||
end
|
end
|
||||||
|
|
||||||
def deserialize(value)
|
def deserialize(value)
|
||||||
|
|||||||
Reference in New Issue
Block a user