Class: StructuredDataToSql::Json::ColumnProfile

Inherits:
Object
  • Object
show all
Defined in:
lib/structured_data_to_sql/json/schema_inferrer.rb

Overview

Accumulates per-column type observations across all records of a table and finalizes them into MySQL column definitions via a widening lattice: unknown -> boolean | integer -> float | datetime -> string (sized into VARCHAR/TEXT/MEDIUMTEXT/LONGTEXT by max byte length).

Constant Summary collapse

ISO_DATETIME =
/\A\d{4}-\d{2}-\d{2}[Tt ]\d{2}:\d{2}:\d{2}(?:\.\d+)?(?:[Zz]|[+-]\d{2}:?\d{2})?\z/

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(raw_dates: false) ⇒ ColumnProfile

Returns a new instance of ColumnProfile.



20
21
22
23
24
25
26
# File 'lib/structured_data_to_sql/json/schema_inferrer.rb', line 20

def initialize(raw_dates: false)
  @raw_dates = raw_dates
  @kind = :unknown
  @max_bytes = 0
  @null_seen = false
  @seen_count = 0
end

Instance Attribute Details

#kindObject (readonly)

Returns the value of attribute kind.



18
19
20
# File 'lib/structured_data_to_sql/json/schema_inferrer.rb', line 18

def kind
  @kind
end

#seen_countObject (readonly)

Returns the value of attribute seen_count.



18
19
20
# File 'lib/structured_data_to_sql/json/schema_inferrer.rb', line 18

def seen_count
  @seen_count
end

Instance Method Details

#finalize(name, row_count) ⇒ Object



51
52
53
54
55
56
57
58
# File 'lib/structured_data_to_sql/json/schema_inferrer.rb', line 51

def finalize(name, row_count)
  ColumnDef.new(
    name: name,
    kind: @kind,
    sql_type: sql_type,
    null: @null_seen || @seen_count < row_count
  )
end

#observe(value) ⇒ Object



28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
# File 'lib/structured_data_to_sql/json/schema_inferrer.rb', line 28

def observe(value)
  @seen_count += 1
  case value
  when nil
    @null_seen = true
  when JsonValue
    @kind = :json
    @max_bytes = [@max_bytes, value.text.bytesize].max
  when true, false
    widen(:boolean)
  when Integer
    widen(:integer)
  when Float
    widen(:float)
  when String
    @max_bytes = [@max_bytes, value.bytesize].max
    widen(!@raw_dates && value.match?(ISO_DATETIME) ? :datetime : :string)
  else
    @max_bytes = [@max_bytes, value.to_s.bytesize].max
    widen(:string)
  end
end