Class: TypedData::Converter

Inherits:
Object
  • Object
show all
Defined in:
lib/typed_data/converter.rb

Instance Method Summary collapse

Constructor Details

#initialize(schema, key_formatter: :bigquery) ⇒ Converter

Returns a new instance of Converter.

Parameters:

  • schema (Hash)

    an Avro schema

  • key_formatter (Symbol) (defaults to: :bigquery)


9
10
11
12
# File 'lib/typed_data/converter.rb', line 9

def initialize(schema, key_formatter: :bigquery)
  @schema = Schema.new(schema)
  @union_type_key_formatter = KeyFormatter.find(key_formatter)
end

Instance Method Details

#convert(data) ⇒ Object

Parameters:

  • data (Hash)


20
21
22
# File 'lib/typed_data/converter.rb', line 20

def convert(data)
  @schema.root_type.accept(self, data)
end

#union_type_key_formatter=(formatter) ⇒ Object



14
15
16
17
# File 'lib/typed_data/converter.rb', line 14

def union_type_key_formatter=(formatter)
  warn "DEPRECATION WARNING: #{__method__} is deprecated. Specify the key_formatter :avsc to TypedData::Converter.new instead."
  @union_type_key_formatter = formatter
end

#visit(type, value) ⇒ Object

Parameters:



26
27
28
# File 'lib/typed_data/converter.rb', line 26

def visit(type, value)
  value
end

#visit_array(type, array) ⇒ Object

Parameters:



76
77
78
79
80
81
82
83
84
85
86
87
88
# File 'lib/typed_data/converter.rb', line 76

def visit_array(type, array)
  array.each_with_object([]) do |value, ret|
    next if value.nil?

    converted_value = type.element_type.accept(self, value)
    if type.element_type.is_a?(Schema::ArrayType)
      # BigQuery doesn't support nested arrays
      ret.concat(converted_value)
    else
      ret << converted_value
    end
  end
end

#visit_bytes(type, value) ⇒ Object

Parameters:



32
33
34
# File 'lib/typed_data/converter.rb', line 32

def visit_bytes(type, value)
  [value].pack("m0")
end

#visit_int(type, logical_type, value) ⇒ Object

Parameters:



39
40
41
42
43
44
45
46
47
48
# File 'lib/typed_data/converter.rb', line 39

def visit_int(type, logical_type, value)
  case logical_type
  when "date"
    (Date.new(1970, 1, 1) + value).to_s
  when "time-millis"
    Time.at(value / 1_000, value % 1_000 * 1_000).utc.strftime("%T.%3N")
  else
    value
  end
end

#visit_long(type, logical_type, value) ⇒ Object

Parameters:



53
54
55
56
57
58
59
60
61
62
63
64
# File 'lib/typed_data/converter.rb', line 53

def visit_long(type, logical_type, value)
  case logical_type
  when "time-micros"
    Time.at(value / 1_000_000, value % 1_000_000).utc.strftime("%T.%6N")
  when "timestamp-millis"
    Time.at(value / 1_000, value % 1_000 * 1_000).utc.strftime("%F %T.%3N")
  when "timestamp-micros"
    Time.at(value / 1_000_000, value % 1_000_000).utc.strftime("%F %T.%6N")
  else
    value
  end
end

#visit_map(type, map) ⇒ Object

Parameters:



92
93
94
95
96
# File 'lib/typed_data/converter.rb', line 92

def visit_map(type, map)
  map.each_with_object([]) do |(key, value), ret|
    ret << { "key" => key, "value" => type.element_type.accept(self, value) }
  end
end

#visit_record(type, record) ⇒ Object

Parameters:



68
69
70
71
72
# File 'lib/typed_data/converter.rb', line 68

def visit_record(type, record)
  record.each_with_object({}) do |(key, value), converted|
    converted[key] = type.find_type(key).accept(self, value)
  end
end

#visit_union(type, types, value) ⇒ Object

Parameters:



101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
# File 'lib/typed_data/converter.rb', line 101

def visit_union(type, types, value)
  element_type = types.find { |t| t.match?(value) }
  if element_type.nil?
    raise Schema::InvalidValue, %Q{the value #{value.inspect} doesn't match the type #{types.map(&:to_s)}}
  end
  converted_value = element_type.accept(self, value)

  if type.nullable_single?
    converted_value
  elsif element_type.is_a?(Schema::NullType)
    {}
  else
    { @union_type_key_formatter.call(element_type.to_s) => converted_value }
  end
end