Class: TypedData::Restorer

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

Instance Method Summary collapse

Constructor Details

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

Returns a new instance of Restorer.

Parameters:

  • schema (Hash)

    an Avro schema

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


10
11
12
13
# File 'lib/typed_data/restorer.rb', line 10

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

Instance Method Details

#restore(data) ⇒ Object

Parameters:

  • data (Hash)


16
17
18
# File 'lib/typed_data/restorer.rb', line 16

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

#visit(type, value) ⇒ Object

Parameters:



22
23
24
# File 'lib/typed_data/restorer.rb', line 22

def visit(type, value)
  value
end

#visit_array(type, array) ⇒ Object

Parameters:



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

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

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

#visit_bytes(type, value) ⇒ Object

Parameters:



28
29
30
# File 'lib/typed_data/restorer.rb', line 28

def visit_bytes(type, value)
  value.unpack("m0").first
end

#visit_int(type, logical_type, value) ⇒ Object

Parameters:



35
36
37
38
39
40
41
42
43
44
45
# File 'lib/typed_data/restorer.rb', line 35

def visit_int(type, logical_type, value)
  case logical_type
  when "date"
    (Date.parse(value) - Date.new(1970, 1, 1)).to_i
  when "time-millis"
    t = Time.parse(value)
    (t.sec + t.min * 60 + t.hour * 60**2) * 10**3 + t.nsec / 10**6
  else
    value
  end
end

#visit_long(type, logical_type, value) ⇒ Object

Parameters:



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

def visit_long(type, logical_type, value)
  case logical_type
  when "time-micros"
    t = Time.parse(value)
    (t.sec + t.min * 60 + t.hour * 60**2) * 10**6 + t.nsec / 10**3
  when "timestamp-millis"
    t = parse_as_utc(value)
    t.to_i * 10**3 + t.nsec / 10**6
  when "timestamp-micros"
    t = parse_as_utc(value)
    t.to_i * 10**6 + t.nsec / 10**3
  else
    value
  end
end

#visit_map(type, array) ⇒ Object

Parameters:



91
92
93
94
95
# File 'lib/typed_data/restorer.rb', line 91

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

#visit_record(type, record) ⇒ Object

Parameters:



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

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

#visit_union(type, types, value) ⇒ Object

Parameters:



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

def visit_union(type, types, value)
  if type.nullable_single?
    return if value.nil?

    element_type = types.find { |t| !t.is_a?(Schema::NullType) }
    element_type.accept(self, value)
  else
    value_without_nil = value.compact
    return if value_without_nil.empty?

    k = value_without_nil.keys.first
    v = value_without_nil.values.first
    element_type = types.find { |t| k == @union_type_key_formatter.call(t.to_s) }
    element_type.accept(self, v)
  end
end