lib/duckdb/converter.rb in duckdb-0.8.1.3 vs lib/duckdb/converter.rb in duckdb-0.9.0
- old
+ new
@@ -1,12 +1,14 @@
# frozen_string_literal: true
require 'date'
+require_relative 'interval'
module DuckDB
module Converter
- HALF_HUGEINT = 1 << 64
+ HALF_HUGEINT_BIT = 64
+ HALF_HUGEINT = 1 << HALF_HUGEINT_BIT
FLIP_HUGEINT = 1 << 63
module_function
def _to_date(year, month, day)
@@ -16,30 +18,22 @@
def _to_time(year, month, day, hour, minute, second, microsecond)
Time.local(year, month, day, hour, minute, second, microsecond)
end
def _to_hugeint_from_vector(lower, upper)
- (upper * HALF_HUGEINT) + lower
+ (upper << HALF_HUGEINT_BIT) + lower
end
def _to_decimal_from_vector(_width, scale, lower, upper)
v = _to_hugeint_from_vector(lower, upper).to_s
v = v.rjust(scale + 1, '0') if v.length < scale
v[-scale, 0] = '.'
BigDecimal(v)
end
def _to_interval_from_vector(months, days, micros)
- hash = { year: 0, month: 0, day: 0, hour: 0, min: 0, sec: 0, usec: 0 }
- hash[:year] = months / 12
- hash[:month] = months % 12
- hash[:day] = days
- hash[:hour] = micros / 3_600_000_000
- hash[:min] = (micros % 3_600_000_000) / 60_000_000
- hash[:sec] = (micros % 60_000_000) / 1_000_000
- hash[:usec] = micros % 1_000_000
- hash
+ Interval.new(interval_months: months, interval_days: days, interval_micros: micros)
end
def _to_uuid_from_vector(lower, upper)
upper = upper ^ FLIP_HUGEINT
upper += HALF_HUGEINT if upper.negative?
@@ -51,61 +45,14 @@
private
def integer_to_hugeint(value)
case value
when Integer
- upper = value / HALF_HUGEINT
- lower = value - upper * HALF_HUGEINT
+ upper = value >> HALF_HUGEINT_BIT
+ lower = value - (upper << HALF_HUGEINT_BIT)
[lower, upper]
else
- raise(ArgumentError, "2nd argument `#{value}` must be Integer.")
+ raise(ArgumentError, "The argument `#{value}` must be Integer.")
end
- end
-
- def iso8601_interval_to_hash(value)
- digit = ''
- time = false
- hash = {}
- hash.default = 0
-
- value.each_char do |c|
- if '-0123456789.'.include?(c)
- digit += c
- elsif c == 'T'
- time = true
- digit = ''
- elsif c == 'M'
- m_interval_to_hash(hash, digit, time)
- digit = ''
- elsif c == 'S'
- s_interval_to_hash(hash, digit)
- digit = ''
- elsif 'YDH'.include?(c)
- hash[c] = digit.to_i
- digit = ''
- elsif c != 'P'
- raise ArgumentError, "The argument `#{value}` can't be parse."
- end
- end
- hash
- end
-
- def m_interval_to_hash(hash, digit, time)
- key = time ? 'TM' : 'M'
- hash[key] = digit.to_i
- end
-
- def s_interval_to_hash(hash, digit)
- sec, msec = digit.split('.')
- hash['S'] = sec.to_i
- hash['MS'] = "#{msec}000000"[0, 6].to_i
- hash['MS'] *= -1 if hash['S'].negative?
- end
-
- def hash_to__append_interval_args(hash)
- months = hash['Y'] * 12 + hash['M']
- days = hash['D']
- micros = (hash['H'] * 3600 + hash['TM'] * 60 + hash['S']) * 1_000_000 + hash['MS']
- [months, days, micros]
end
end
end