class ODBCAdapter::ColumnMetadata

Constants

GENERICS

Attributes

adapter[R]

Public Class Methods

new(adapter) click to toggle source
# File lib/odbc_adapter/column_metadata.rb, line 20
def initialize(adapter)
  @adapter = adapter
end

Public Instance Methods

native_database_types() click to toggle source
# File lib/odbc_adapter/column_metadata.rb, line 24
def native_database_types
  grouped = reported_types.group_by { |row| row[1] }

  GENERICS.each_with_object({}) do |(abstract, candidates), mapped|
    candidates.detect do |candidate|
      next unless grouped[candidate]
      mapped[abstract] = native_type_mapping(abstract, grouped[candidate])
    end
  end
end

Private Instance Methods

native_type_mapping(abstract, rows) click to toggle source

Creates a Hash describing a mapping from an abstract type to a DBMS native type for use by native_database_types

# File lib/odbc_adapter/column_metadata.rb, line 39
def native_type_mapping(abstract, rows)
  # The appropriate SQL for :primary_key is hard to derive as
  # ODBC doesn't provide any info on a DBMS's native syntax for
  # autoincrement columns. So we use a lookup instead.
  return adapter.class::PRIMARY_KEY if abstract == :primary_key
  selected_row = rows[0]

  # If more than one native type corresponds to the SQL type we're
  # handling, the type in the first descriptor should be the
  # best match, because the ODBC specification states that
  # SQLGetTypeInfo returns the results ordered by SQL type and then by
  # how closely the native type maps to that SQL type.
  # But, for :text and :binary, select the native type with the
  # largest capacity. (Compare SQLGetTypeInfo:COLUMN_SIZE values)
  selected_row = rows.max_by { |row| row[2] } if %i[text binary].include?(abstract)
  result = { name: selected_row[0] } # SQLGetTypeInfo: TYPE_NAME

  create_params = selected_row[5]
  # Depending on the column type, the CREATE_PARAMS keywords can
  # include length, precision or scale.
  if create_params && !create_params.strip.empty? && abstract != :decimal
    result[:limit] = selected_row[2] # SQLGetTypeInfo: COL_SIZE
  end

  result
end
reported_types() click to toggle source
# File lib/odbc_adapter/column_metadata.rb, line 66
def reported_types
  @reported_types ||=
    begin
      stmt = adapter.raw_connection.types
      stmt.fetch_all
    ensure
      stmt.drop unless stmt.nil?
    end
end