Class: Innodb::DataType::DecimalType

Inherits:
Object
  • Object
show all
Defined in:
lib/innodb/data_type.rb

Overview

MySQL’s Fixed-Point Type (DECIMAL), stored in InnoDB as a binary string.

Constant Summary collapse

MAX_DIGITS_PER_INTEGER =

The value is stored as a sequence of signed big-endian integers, each representing up to 9 digits of the integral and fractional parts. The first integer of the integral part and/or the last integer of the fractional part might be compressed (or packed) and are of variable length. The remaining integers (if any) are uncompressed and 32 bits wide.

9
BYTES_PER_DIGIT =
[0, 1, 1, 2, 2, 3, 3, 4, 4, 4].freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(base_type, modifiers, properties) ⇒ DecimalType

Returns a new instance of DecimalType.



108
109
110
111
112
113
114
115
116
117
118
# File 'lib/innodb/data_type.rb', line 108

def initialize(base_type, modifiers, properties)
  precision, scale = sanity_check(modifiers)
  integral = precision - scale
  @uncomp_integral = integral / MAX_DIGITS_PER_INTEGER
  @uncomp_fractional = scale / MAX_DIGITS_PER_INTEGER
  @comp_integral = integral - (@uncomp_integral * MAX_DIGITS_PER_INTEGER)
  @comp_fractional = scale - (@uncomp_fractional * MAX_DIGITS_PER_INTEGER)
  @width = (@uncomp_integral * 4) + BYTES_PER_DIGIT[@comp_integral] +
           (@comp_fractional * 4) + BYTES_PER_DIGIT[@comp_fractional]
  @name = Innodb::DataType.make_name(base_type, modifiers, properties)
end

Instance Attribute Details

#nameObject (readonly)

Returns the value of attribute name.



96
97
98
# File 'lib/innodb/data_type.rb', line 96

def name
  @name
end

#widthObject (readonly)

Returns the value of attribute width.



97
98
99
# File 'lib/innodb/data_type.rb', line 97

def width
  @width
end

Instance Method Details

#value(data) ⇒ Object



120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
# File 'lib/innodb/data_type.rb', line 120

def value(data)
  # Strings representing the integral and fractional parts.
  intg = "".dup
  frac = "".dup

  stream = StringIO.new(data)
  mask = sign_mask(stream)

  intg << get_digits(stream, mask, @comp_integral)

  (1..@uncomp_integral).each do
    intg << get_digits(stream, mask, MAX_DIGITS_PER_INTEGER)
  end

  (1..@uncomp_fractional).each do
    frac << get_digits(stream, mask, MAX_DIGITS_PER_INTEGER)
  end

  frac << get_digits(stream, mask, @comp_fractional)
  frac = "0" if frac.empty?

  # Convert to something resembling a string representation.
  str = "#{mask.to_s.chop}#{intg}.#{frac}"

  BigDecimal(str).to_s("F")
end