module ODBCAdapter::DatabaseStatements

Constants

SQL_NO_NULLS

ODBC constants missing from Christian Werner's Ruby ODBC driver

SQL_NULLABLE
SQL_NULLABLE_UNKNOWN

Public Instance Methods

begin_db_transaction() click to toggle source

Begins the transaction (and turns off auto-committing).

# File lib/odbc_adapter/database_statements.rb, line 51
def begin_db_transaction
  @connection.autocommit = false
end
commit_db_transaction() click to toggle source

Commits the transaction (and turns on auto-committing).

# File lib/odbc_adapter/database_statements.rb, line 56
def commit_db_transaction
  @connection.commit
  @connection.autocommit = true
end
default_sequence_name(table, _column) click to toggle source

Returns the default sequence name for a table. Used for databases which don't support an autoincrementing column type, but do support sequences.

# File lib/odbc_adapter/database_statements.rb, line 71
def default_sequence_name(table, _column)
  "#{table}_seq"
end
exec_delete(sql, name, binds) click to toggle source

Executes delete sql statement in the context of this connection using binds as the bind substitutes. name is logged along with the executed sql statement.

# File lib/odbc_adapter/database_statements.rb, line 45
def exec_delete(sql, name, binds)
  execute(sql, name, binds)
end
Also aliased as: exec_update
exec_query(sql, name = 'SQL', binds = [], prepare: false) click to toggle source

Executes sql statement in the context of this connection using binds as the bind substitutes. name is logged along with the executed sql statement.

# File lib/odbc_adapter/database_statements.rb, line 23
def exec_query(sql, name = 'SQL', binds = [], prepare: false) # rubocop:disable Lint/UnusedMethodArgument
  log(sql, name) do
    stmt =
      if prepared_statements
        @connection.run(sql, *prepared_binds(binds))
      else
        @connection.run(sql)
      end

    columns = stmt.columns
    values  = stmt.to_a
    stmt.drop

    values = dbms_type_cast(columns.values, values)
    column_names = columns.keys.map { |key| format_case(key) }
    ActiveRecord::Result.new(column_names, values)
  end
end
exec_rollback_db_transaction() click to toggle source

Rolls back the transaction (and turns on auto-committing). Must be done if the transaction block raises an exception or returns false.

# File lib/odbc_adapter/database_statements.rb, line 63
def exec_rollback_db_transaction
  @connection.rollback
  @connection.autocommit = true
end
exec_update(sql, name, binds)
Alias for: exec_delete
execute(sql, name = nil, binds = []) click to toggle source

Executes the SQL statement in the context of this connection. Returns the number of rows affected.

# File lib/odbc_adapter/database_statements.rb, line 10
def execute(sql, name = nil, binds = [])
  log(sql, name) do
    if prepared_statements
      @connection.do(sql, *prepared_binds(binds))
    else
      @connection.do(sql)
    end
  end
end

Private Instance Methods

dbms_type_cast(_columns, values) click to toggle source

A custom hook to allow end users to overwrite the type casting before it is returned to ActiveRecord. Useful before a full adapter has made its way back into this repository.

# File lib/odbc_adapter/database_statements.rb, line 80
def dbms_type_cast(_columns, values)
  values
end
format_case(identifier) click to toggle source

Assume received identifier is in DBMS's data dictionary case.

# File lib/odbc_adapter/database_statements.rb, line 85
def format_case(identifier)
  if database_metadata.upcase_identifiers?
    identifier =~ /[a-z]/ ? identifier : identifier.downcase
  else
    identifier
  end
end
native_case(identifier) click to toggle source

In general, ActiveRecord uses lowercase attribute names. This may conflict with the database's data dictionary case.

The ODBCAdapter uses the following conventions for databases which report SQL_IDENTIFIER_CASE = SQL_IC_UPPER:

  • if a name is returned from the DBMS in all uppercase, convert it to lowercase before returning it to ActiveRecord.

  • if a name is returned from the DBMS in lowercase or mixed case, assume the underlying schema object's name was quoted when the schema object was created. Leave the name untouched before returning it to ActiveRecord.

  • before making an ODBC catalog call, if a supplied identifier is all lowercase, convert it to uppercase. Leave mixed case or all uppercase identifiers unchanged.

  • columns created with quoted lowercase names are not supported.

Converts an identifier to the case conventions used by the DBMS. Assume received identifier is in ActiveRecord case.

# File lib/odbc_adapter/database_statements.rb, line 111
def native_case(identifier)
  if database_metadata.upcase_identifiers?
    identifier =~ /[A-Z]/ ? identifier : identifier.upcase
  else
    identifier
  end
end
nullability(col_name, is_nullable, nullable) click to toggle source

Assume column is nullable if nullable == SQL_NULLABLE_UNKNOWN

# File lib/odbc_adapter/database_statements.rb, line 120
def nullability(col_name, is_nullable, nullable)
  not_nullable = (!is_nullable || !nullable.to_s.match('NO').nil?)
  result = !(not_nullable || nullable == SQL_NO_NULLS)

  # HACK!
  # MySQL native ODBC driver doesn't report nullability accurately.
  # So force nullability of 'id' columns
  col_name == 'id' ? false : result
end
prepared_binds(binds) click to toggle source
# File lib/odbc_adapter/database_statements.rb, line 130
def prepared_binds(binds)
  prepare_binds_for_database(binds).map { |bind| _type_cast(bind) }
end