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]

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(base_type, modifiers, properties) ⇒ DecimalType

Returns a new instance of DecimalType.



102
103
104
105
106
107
108
109
110
111
112
# File 'lib/innodb/data_type.rb', line 102

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.



91
92
93
# File 'lib/innodb/data_type.rb', line 91

def name
  @name
end

#widthObject (readonly)

Returns the value of attribute width.



91
92
93
# File 'lib/innodb/data_type.rb', line 91

def width
  @width
end

Instance Method Details

#value(data) ⇒ Object



114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
# File 'lib/innodb/data_type.rb', line 114

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

  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)

  # Convert to something resembling a string representation.
  str = mask.to_s.chop + intg + '.' + frac

  BigDecimal.new(str).to_s('F')
end