class Innodb::Field

Constants

EXTERN_FIELD_SIZE

Size of a reference to data stored externally to the page.

ExternReference

Attributes

data_type[R]
name[R]
nullable[R]
position[R]

Public Class Methods

new(position, name, type_definition, *properties) click to toggle source
# File lib/innodb/field.rb, line 26
def initialize(position, name, type_definition, *properties)
  @position = position
  @name = name
  @nullable = !properties.delete(:NOT_NULL)
  base_type, modifiers = parse_type_definition(type_definition.to_s)
  @data_type = Innodb::DataType.new(base_type, modifiers, properties)
end

Public Instance Methods

blob?() click to toggle source
# File lib/innodb/field.rb, line 57
def blob?
  @data_type.is_a?(Innodb::DataType::BlobType)
end
extern(cursor, record) click to toggle source

Read an InnoDB external pointer field.

# File lib/innodb/field.rb, line 95
def extern(cursor, record)
  return unless extern?(record)

  cursor.name(@name) { read_extern(cursor) }
end
extern?(record) click to toggle source

Return whether a part of this field is stored externally (off-page).

# File lib/innodb/field.rb, line 45
def extern?(record)
  record.header.externs.include?(@name)
end
length(record) click to toggle source

Return the actual length of this variable-length field.

# File lib/innodb/field.rb, line 62
def length(record)
  if record.header.lengths.include?(@name)
    len = record.header.lengths[@name]
    raise "Fixed-length mismatch" unless variable? || len == @data_type.width
  else
    len = @data_type.width
  end
  extern?(record) ? len - EXTERN_FIELD_SIZE : len
end
null?(record) click to toggle source

Return whether this field is NULL.

# File lib/innodb/field.rb, line 40
def null?(record)
  nullable? && record.header.nulls.include?(@name)
end
nullable?() click to toggle source

Return whether this field can be NULL.

# File lib/innodb/field.rb, line 35
def nullable?
  @nullable
end
read(cursor, field_length) click to toggle source

Read an InnoDB encoded data field.

# File lib/innodb/field.rb, line 73
def read(cursor, field_length)
  cursor.name(@data_type.name) { cursor.read_bytes(field_length) }
end
value(cursor, record) click to toggle source

Read the data value (e.g. encoded in the data).

# File lib/innodb/field.rb, line 88
def value(cursor, record)
  return :NULL if null?(record)

  value_by_length(cursor, length(record))
end
value_by_length(cursor, field_length) click to toggle source
# File lib/innodb/field.rb, line 77
def value_by_length(cursor, field_length)
  if @data_type.respond_to?(:read)
    cursor.name(@data_type.name) { @data_type.read(cursor) }
  elsif @data_type.respond_to?(:value)
    @data_type.value(read(cursor, field_length))
  else
    read(cursor, field_length)
  end
end
variable?() click to toggle source
# File lib/innodb/field.rb, line 49
def variable?
  [
    Innodb::DataType::BlobType,
    Innodb::DataType::VariableBinaryType,
    Innodb::DataType::VariableCharacterType,
  ].any? { |c| @data_type.is_a?(c) }
end

Private Instance Methods

parse_type_definition(type_string) click to toggle source

Parse a data type definition and extract the base type and any modifiers.

# File lib/innodb/field.rb, line 117
def parse_type_definition(type_string)
  matches = /^([a-zA-Z0-9_]+)(\(([0-9, ]+)\))?$/.match(type_string)
  return unless matches

  base_type = matches[1].upcase.to_sym
  return [base_type, []] unless matches[3]

  [base_type, matches[3].sub(/ /, "").split(",").map(&:to_i)]
end
read_extern(cursor) click to toggle source

Return an external reference field. An extern field contains the page address and the length of the externally stored part of the record data.

# File lib/innodb/field.rb, line 105
def read_extern(cursor)
  cursor.name("extern") do |c|
    ExternReference.new(
      space_id: c.name("space_id") { c.read_uint32 },
      page_number: c.name("page_number") { c.read_uint32 },
      offset: c.name("offset") { c.read_uint32 },
      length: c.name("length") { c.read_uint64 & 0x3fffffff }
    )
  end
end