Class: Avro::LogicalTypes::BytesDecimal

Inherits:
LogicalTypeWithSchema show all
Defined in:
lib/avro/logical_types.rb

Overview

Logical type to handle arbitrary-precision decimals using byte array.

The byte array contains the two’s-complement representation of the unscaled integer value in big-endian byte order.

Constant Summary collapse

ERROR_INSUFFICIENT_PRECISION =

Messages for exceptions

'Precision is too small'
ERROR_ROUNDING_NECESSARY =
'Rounding necessary'
ERROR_VALUE_MUST_BE_NUMERIC =
'value must be numeric'
PACK_UNSIGNED_CHARS =

The pattern used to pack up the byte array (8 bit unsigned integer/char)

'C*'
TEN =

The number 10 as BigDecimal

BigDecimal(10).freeze

Instance Attribute Summary collapse

Attributes inherited from LogicalTypeWithSchema

#schema

Instance Method Summary collapse

Constructor Details

#initialize(schema) ⇒ BytesDecimal

Build a new decimal logical type

Parameters:

  • schema (Avro::Schema)

    The schema defining precision and scale for the conversion



99
100
101
102
103
104
105
# File 'lib/avro/logical_types.rb', line 99

def initialize(schema)
  super

  @scale     = schema.scale.to_i
  @precision = schema.precision.to_i
  @factor    = TEN ** @scale
end

Instance Attribute Details

#precisionInteger (readonly)

Returns The number of total digits supported by the decimal.

Returns:

  • (Integer)

    The number of total digits supported by the decimal



88
89
90
# File 'lib/avro/logical_types.rb', line 88

def precision
  @precision
end

#scaleInteger (readonly)

Returns The number of fractional digits.

Returns:

  • (Integer)

    The number of fractional digits



92
93
94
# File 'lib/avro/logical_types.rb', line 92

def scale
  @scale
end

Instance Method Details

#decode(stream) ⇒ BigDecimal

Decode a byte array (in form of a string) into a BigDecimal of the given precision and scale

Parameters:

  • stream (String)

    The byte array to decode

Returns:

  • (BigDecimal)


133
134
135
# File 'lib/avro/logical_types.rb', line 133

def decode(stream)
  from_byte_array(stream) / @factor
end

#encode(value) ⇒ Object

Encode the provided value into a byte array

Parameters:

  • value (BigDecimal, Float, Integer)

    The numeric value to encode

Raises:

  • (ArgumentError)

    If the provided value is not a numeric type

  • (RangeError)

    If the provided value has a scale higher than the schema permits, or does not fit into the schema’s precision



119
120
121
122
123
# File 'lib/avro/logical_types.rb', line 119

def encode(value)
  raise ArgumentError, ERROR_VALUE_MUST_BE_NUMERIC unless value.is_a?(Numeric)

  to_byte_array(unscaled_value(value.to_d)).pack(PACK_UNSIGNED_CHARS).freeze
end