Class: RubyVolt::DataType::Decimal

Inherits:
FixedSize show all
Defined in:
lib/ruby_volt/data_type/basic/fixed_size/decimal.rb

Constant Summary collapse

DIRECTIVE =
'C16'
NULL_INDICATOR =

SQL NULL indicator for object type serializations

-170141183460469231731687303715884105728 # SQL NULL indicator for object type serializations
LENGTH =
16
PRECISION =
38
SCALE =
12

Class Method Summary collapse

Methods inherited from Basic

bytesToInt, intToBytes

Methods inherited from RubyVolt::DataType

classifyDataType, testpacking, voltDataType

Class Method Details

.pack(val) ⇒ Object



14
15
16
# File 'lib/ruby_volt/data_type/basic/fixed_size/decimal.rb', line 14

def pack(val)
  ((val == self::NULL_INDICATOR) || val.nil?) ? intToBytes(self::LENGTH, self::NULL_INDICATOR) : serialize(val)
end

.serialize(val) ⇒ Object

Raises:

  • (::ArgumentError)


26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
# File 'lib/ruby_volt/data_type/basic/fixed_size/decimal.rb', line 26

def serialize(val)
  num = case val
  when BigDecimal then val
  else val.to_d
  end
  sign, digits, base, exponent = *num.split
  scale = digits.size - exponent
  precision = digits.size
  raise(::ArgumentError, "Scale of this decimal is #{scale} and the max is #{self::SCALE}") if scale > self::SCALE
  rest = precision - scale
  raise(::ArgumentError, "Precision to the left of the decimal point is #{rest} and the max is #{self::PRECISION-self::SCALE}") if rest > 26
  scale_factor = self::SCALE - scale
  unscaled_int = sign * digits.to_i * base ** scale_factor # Unscaled integer
  intToBytes(self::LENGTH, unscaled_int)
end

.unpack(bytes) ⇒ Object



18
19
20
21
22
23
24
# File 'lib/ruby_volt/data_type/basic/fixed_size/decimal.rb', line 18

def unpack(bytes)
  if (unscaled = bytesToInt(self::LENGTH, bytes.read(self::LENGTH))) && (unscaled != self::NULL_INDICATOR)
    unscaled = unscaled.to_s
    scaled = unscaled.insert(unscaled.size - self::SCALE, ".")
    BigDecimal(scaled)
  end
end