class ActiveRecord::ConnectionAdapters::ODBCAdapter

Constants

ADAPTER_NAME
BOOLEAN_TYPE
ERR_CONNECTION_FAILED_MESSAGE
ERR_CONNECTION_FAILED_REGEX
ERR_DUPLICATE_KEY_VALUE
ERR_QUERY_TIMED_OUT
ERR_QUERY_TIMED_OUT_MESSAGE

Attributes

database_metadata[R]

The object that stores the information that is fetched from the DBMS when a connection is first established.

Public Class Methods

new(connection, logger, config, database_metadata) click to toggle source
Calls superclass method
# File lib/active_record/connection_adapters/odbc_adapter.rb, line 87
def initialize(connection, logger, config, database_metadata)
  configure_time_options(connection)
  super(connection, logger, config)
  @database_metadata = database_metadata
end

Public Instance Methods

active?() click to toggle source

Checks whether the connection to the database is still active. This includes checking whether the database is actually capable of responding, i.e. whether the connection isn't stale.

# File lib/active_record/connection_adapters/odbc_adapter.rb, line 109
def active?
  @connection.connected?
end
adapter_name() click to toggle source

Returns the human-readable name of the adapter.

# File lib/active_record/connection_adapters/odbc_adapter.rb, line 94
def adapter_name
  ADAPTER_NAME
end
disconnect!() click to toggle source

Disconnects from the database if already connected. Otherwise, this method does nothing.

# File lib/active_record/connection_adapters/odbc_adapter.rb, line 131
def disconnect!
  @connection.disconnect if @connection.connected?
end
new_column(name, default, sql_type_metadata, null, table_name, default_function = nil, collation = nil, native_type = nil) click to toggle source

Build a new column object from the given options. Effectively the same as super except that it also passes in the native type. rubocop:disable Metrics/ParameterLists

# File lib/active_record/connection_adapters/odbc_adapter.rb, line 138
def new_column(name, default, sql_type_metadata, null, table_name, default_function = nil, collation = nil, native_type = nil)
  ::ODBCAdapter::Column.new(name, default, sql_type_metadata, null, table_name, default_function, collation, native_type)
end
reconnect!() click to toggle source

Disconnects from the database if already connected, and establishes a new connection with the database.

Calls superclass method
# File lib/active_record/connection_adapters/odbc_adapter.rb, line 115
def reconnect!
  disconnect!
  odbc_module = @config[:encoding] == 'utf8' ? ODBC_UTF8 : ODBC
  @connection =
    if @config.key?(:dsn)
      odbc_module.connect(@config[:dsn], @config[:username], @config[:password])
    else
      odbc_module::Database.new.drvconnect(@config[:driver])
    end
  configure_time_options(@connection)
  super
end
Also aliased as: reset!
reset!()
Alias for: reconnect!
supports_migrations?() click to toggle source

Does this adapter support migrations? Backend specific, as the abstract adapter always returns false.

# File lib/active_record/connection_adapters/odbc_adapter.rb, line 100
def supports_migrations?
  true
end

Protected Instance Methods

initialize_type_map(map) click to toggle source

Build the type map for ActiveRecord Here, ODBC and ODBC_UTF8 constants are interchangeable

# File lib/active_record/connection_adapters/odbc_adapter.rb, line 146
def initialize_type_map(map)
  map.register_type 'boolean',              Type::Boolean.new
  map.register_type ODBC::SQL_CHAR,         Type::String.new
  map.register_type ODBC::SQL_LONGVARCHAR,  Type::Text.new
  map.register_type ODBC::SQL_TINYINT,      Type::Integer.new(limit: 4)
  map.register_type ODBC::SQL_SMALLINT,     Type::Integer.new(limit: 8)
  map.register_type ODBC::SQL_INTEGER,      Type::Integer.new(limit: 16)
  map.register_type ODBC::SQL_BIGINT,       Type::BigInteger.new(limit: 32)
  map.register_type ODBC::SQL_REAL,         Type::Float.new(limit: 24)
  map.register_type ODBC::SQL_FLOAT,        Type::Float.new
  map.register_type ODBC::SQL_DOUBLE,       Type::Float.new(limit: 53)
  map.register_type ODBC::SQL_DECIMAL,      Type::Float.new
  map.register_type ODBC::SQL_NUMERIC,      Type::Integer.new
  map.register_type ODBC::SQL_BINARY,       Type::Binary.new
  map.register_type ODBC::SQL_DATE,         Type::Date.new
  map.register_type ODBC::SQL_DATETIME,     Type::DateTime.new
  map.register_type ODBC::SQL_TIME,         Type::Time.new
  map.register_type ODBC::SQL_TIMESTAMP,    Type::DateTime.new
  map.register_type ODBC::SQL_GUID,         Type::String.new

  alias_type map, ODBC::SQL_BIT,            'boolean'
  alias_type map, ODBC::SQL_VARCHAR,        ODBC::SQL_CHAR
  alias_type map, ODBC::SQL_WCHAR,          ODBC::SQL_CHAR
  alias_type map, ODBC::SQL_WVARCHAR,       ODBC::SQL_CHAR
  alias_type map, ODBC::SQL_WLONGVARCHAR,   ODBC::SQL_LONGVARCHAR
  alias_type map, ODBC::SQL_VARBINARY,      ODBC::SQL_BINARY
  alias_type map, ODBC::SQL_LONGVARBINARY,  ODBC::SQL_BINARY
  alias_type map, ODBC::SQL_TYPE_DATE,      ODBC::SQL_DATE
  alias_type map, ODBC::SQL_TYPE_TIME,      ODBC::SQL_TIME
  alias_type map, ODBC::SQL_TYPE_TIMESTAMP, ODBC::SQL_TIMESTAMP
end
translate_exception(exception, message) click to toggle source

Translate an exception from the native DBMS to something usable by ActiveRecord.

Calls superclass method
# File lib/active_record/connection_adapters/odbc_adapter.rb, line 180
def translate_exception(exception, message)
  error_number = exception.message[/^\d+/].to_i

  if error_number == ERR_DUPLICATE_KEY_VALUE
    ActiveRecord::RecordNotUnique.new(message, exception)
  elsif error_number == ERR_QUERY_TIMED_OUT || exception.message =~ ERR_QUERY_TIMED_OUT_MESSAGE
    ::ODBCAdapter::QueryTimeoutError.new(message, exception)
  elsif exception.message.match(ERR_CONNECTION_FAILED_REGEX) || exception.message =~ ERR_CONNECTION_FAILED_MESSAGE
    begin
      reconnect!
      ::ODBCAdapter::ConnectionFailedError.new(message, exception)
    rescue => e
      puts "unable to reconnect #{e}"
    end
  else
    super
  end
end

Private Instance Methods

alias_type(map, new_type, old_type) click to toggle source

Can't use the built-in ActiveRecord map#alias_type because it doesn't work with non-string keys, and in our case the keys are (almost) all numeric

# File lib/active_record/connection_adapters/odbc_adapter.rb, line 204
def alias_type(map, new_type, old_type)
  map.register_type(new_type) do |_, *args|
    map.lookup(old_type, *args)
  end
end
configure_time_options(connection) click to toggle source

Ensure ODBC is mapping time-based fields to native ruby objects

# File lib/active_record/connection_adapters/odbc_adapter.rb, line 211
def configure_time_options(connection)
  connection.use_time = true
end