module ActiveRecord::ConnectionAdapters::Fb::DatabaseStatements

Public Instance Methods

begin_db_transaction() click to toggle source

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

# File lib/active_record/connection_adapters/fb/database_statements.rb, line 36
def begin_db_transaction
  log('begin transaction', nil) do
    begin_isolated_db_transaction(default_transaction_isolation)
  end
end
begin_isolated_db_transaction(isolation) click to toggle source

Allows providing the :transaction option to ActiveRecord::Base.transaction in 4.0.2+. Can accept verbatim isolation options like ‘WAIT READ COMMITTED’

# File lib/active_record/connection_adapters/fb/database_statements.rb, line 54
def begin_isolated_db_transaction(isolation)
  @connection.transaction transaction_isolation_levels.fetch(isolation, isolation)
end
commit_db_transaction() click to toggle source

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

# File lib/active_record/connection_adapters/fb/database_statements.rb, line 59
def commit_db_transaction
  log('commit transaction', nil) { @connection.commit }
end
default_sequence_name(table_name, _column = nil) click to toggle source
# File lib/active_record/connection_adapters/fb/database_statements.rb, line 69
def default_sequence_name(table_name, _column = nil)
  "#{table_name.to_s.tr('-', '_')[0, table_name_length - 4]}_seq"
end
exec_query(sql, name = 'SQL', binds = []) 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/active_record/connection_adapters/fb/database_statements.rb, line 20
def exec_query(sql, name = 'SQL', binds = [])
  translate_and_log(sql, binds, name) do |args|
    result, rows = @connection.execute(*args) do |cursor|
      [cursor.fields, cursor.fetchall]
    end
    next result unless result.respond_to?(:map)
    cols = result.map { |col| col.name }
    ActiveRecord::Result.new(cols, rows)
  end
end
execute(sql, name = nil) click to toggle source
# File lib/active_record/connection_adapters/fb/database_statements.rb, line 11
def execute(sql, name = nil)
  translate_and_log(sql, [], name) do |args|
    @connection.execute(*args)
  end
end
explain(arel, binds = []) click to toggle source
# File lib/active_record/connection_adapters/fb/database_statements.rb, line 31
def explain(arel, binds = [])
  to_sql(arel, binds)
end
next_sequence_value(sequence_name) click to toggle source

Uses the raw connection to get the next sequence value.

# File lib/active_record/connection_adapters/fb/database_statements.rb, line 81
def next_sequence_value(sequence_name)
  @connection.query("SELECT NEXT VALUE FOR #{sequence_name} FROM RDB$DATABASE")[0][0]
end
reset_sequence!(table, column, sequence = nil) click to toggle source

Set the sequence to the max value of the table’s column.

# File lib/active_record/connection_adapters/fb/database_statements.rb, line 74
def reset_sequence!(table, column, sequence = nil)
  sequence ||= default_sequence_name(table, column)
  max_id = select_value("select max(#{column}) from #{table}")
  execute("alter sequence #{sequence} restart with #{max_id}")
end
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/active_record/connection_adapters/fb/database_statements.rb, line 65
def rollback_db_transaction
  log('rollback transaction', nil) { @connection.rollback }
end
select_rows(sql, name = nil, binds = []) click to toggle source

Returns an array of arrays containing the field values. Order is the same as that returned by columns.

# File lib/active_record/connection_adapters/fb/database_statements.rb, line 7
def select_rows(sql, name = nil, binds = [])
  exec_query(sql, name, binds).to_a.map(&:values)
end
transaction_isolation_levels() click to toggle source

Default isolation levels for transactions. This method exists in 4.0.2+, so it’s here for backward compatibility with AR 3

# File lib/active_record/connection_adapters/fb/database_statements.rb, line 44
def transaction_isolation_levels
  {
    read_committed:   "READ COMMITTED",
    repeatable_read:  "REPEATABLE READ",
    serializable:     "SERIALIZABLE"
  }
end

Protected Instance Methods

last_inserted_id(_result) click to toggle source

Since the ID is prefetched and passed to insert, this method is useless. Overriding this method allows us to avoid overriding insert.

# File lib/active_record/connection_adapters/fb/database_statements.rb, line 96
def last_inserted_id(_result)
  nil
end
select(sql, name = nil, binds = []) click to toggle source

Returns an array of record hashes with the column names as keys and column values as values. ActiveRecord >= 4 returns an ActiveRecord::Result.

# File lib/active_record/connection_adapters/fb/database_statements.rb, line 89
def select(sql, name = nil, binds = [])
  result = exec_query(sql, name, binds)
  ::ActiveRecord::VERSION::MAJOR > 3 ? result : result.to_a
end

Private Instance Methods

translate_and_log(sql, binds = [], name = nil) { |sql, *values| ... } click to toggle source
# File lib/active_record/connection_adapters/fb/database_statements.rb, line 102
def translate_and_log(sql, binds = [], name = nil)
  if ActiveRecord::VERSION::STRING < "4.2.0"
    values = binds.map { |b| type_cast(*b.reverse) }
  else
    values = []
  end

  if sql =~ /(CREATE TABLE|ALTER TABLE)/
    sql.gsub!(/(\@BINDDATE|BINDDATE\@)/m, '\'')
  else
    sql.gsub!(/\@BINDBINARY(.*?)BINDBINARY\@/m) do |extract|
      values << decode(extract[11...-11]) and '?'
    end

    sql.gsub!(/\@BINDDATE(.*?)BINDDATE\@/m) do |extract|
      values << extract[9...-9] and '?'
    end
  end

  log(sql, name, binds) { yield [sql, *values] }
end