module ActiveRecord::ConnectionAdapters::DatabaseStatements - activerecord-4.2.5.2 Documentation

# module ActiveRecord::ConnectionAdapters::DatabaseStatements

### Public Class Methods

new() click to toggle source
Calls superclass method

    # File lib/active_record/connection_adapters/abstract/database_statements.rb, line 4
    def initialize
      super
      reset_transaction
    end

### Public Instance Methods

add_transaction_record(record) click to toggle source

Register a record with the current transaction so that its after_commit and after_rollback callbacks can be called.

    # File lib/active_record/connection_adapters/abstract/database_statements.rb, line 233
    def add_transaction_record(record)
      current_transaction.add_record(record)
    end

begin_db_transaction() click to toggle source

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

    # File lib/active_record/connection_adapters/abstract/database_statements.rb, line 242
    def begin_db_transaction()    end

begin_isolated_db_transaction(isolation) click to toggle source

Begins the transaction with the isolation level set. Raises an error by default; adapters that support setting the isolation level should implement this method.

    # File lib/active_record/connection_adapters/abstract/database_statements.rb, line 256
    def begin_isolated_db_transaction(isolation)
      raise ActiveRecord::TransactionIsolationError, "adapter does not support setting transaction isolation"
    end

commit_db_transaction() click to toggle source

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

    # File lib/active_record/connection_adapters/abstract/database_statements.rb, line 261
    def commit_db_transaction()   end

delete(arel, name = nil, binds = []) click to toggle source

Executes the delete statement and returns the number of rows affected.

    # File lib/active_record/connection_adapters/abstract/database_statements.rb, line 118
    def delete(arel, name = nil, binds = [])
      exec_delete(to_sql(arel, binds), name, binds)
    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/active_record/connection_adapters/abstract/database_statements.rb, line 82
    def exec_delete(sql, name, binds)
      exec_query(sql, name, binds)
    end

exec_insert(sql, name, binds, pk = nil, sequence_name = nil) click to toggle source

Executes insert `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/abstract/database_statements.rb, line 75
    def exec_insert(sql, name, binds, pk = nil, sequence_name = nil)
      exec_query(sql, name, binds)
    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/abstract/database_statements.rb, line 69
    def exec_query(sql, name = 'SQL', binds = [])
    end

exec_update(sql, name, binds) click to toggle source

Executes update `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/abstract/database_statements.rb, line 94
    def exec_update(sql, name, binds)
      exec_query(sql, name, binds)
    end

execute(sql, name = nil) click to toggle source

Executes the SQL statement in the context of this connection.

    # File lib/active_record/connection_adapters/abstract/database_statements.rb, line 62
    def execute(sql, name = nil)
    end

insert(arel, name = nil, pk = nil, id_value = nil, sequence_name = nil, binds = []) click to toggle source

Returns the last auto-generated ID from the affected table.

`id_value` will be returned unless the value is nil, in which case the database will attempt to calculate the last inserted id and return that value.

If the next id was calculated in advance (as in Oracle), it should be passed in as `id_value`.

    # File lib/active_record/connection_adapters/abstract/database_statements.rb, line 106
    def insert(arel, name = nil, pk = nil, id_value = nil, sequence_name = nil, binds = [])
      sql, binds = sql_for_insert(to_sql(arel, binds), pk, id_value, sequence_name, binds)
      value      = exec_insert(sql, name, binds, pk, sequence_name)
      id_value || last_inserted_id(value)
    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/abstract/database_statements.rb, line 265
    def rollback_db_transaction
      exec_rollback_db_transaction
    end

select_all(arel, name = nil, binds = []) click to toggle source

Returns an ActiveRecord::Result instance.

    # File lib/active_record/connection_adapters/abstract/database_statements.rb, line 30
    def select_all(arel, name = nil, binds = [])
      arel, binds = binds_from_relation arel, binds
      select(to_sql(arel, binds), name, binds)
    end

select_one(arel, name = nil, binds = []) click to toggle source

Returns a record hash with the column names as keys and column values as values.

    # File lib/active_record/connection_adapters/abstract/database_statements.rb, line 37
    def select_one(arel, name = nil, binds = [])
      select_all(arel, name, binds).first
    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/abstract/database_statements.rb, line 57
    def select_rows(sql, name = nil, binds = [])
    end

select_value(arel, name = nil, binds = []) click to toggle source

Returns a single value from a record

    # File lib/active_record/connection_adapters/abstract/database_statements.rb, line 42
    def select_value(arel, name = nil, binds = [])
      if result = select_one(arel, name, binds)
        result.values.first
      end
    end

select_values(arel, name = nil) click to toggle source

Returns an array of the values of the first column in a select:

    select_values("SELECT id FROM companies LIMIT 3") => [1,2,3]

    # File lib/active_record/connection_adapters/abstract/database_statements.rb, line 50
    def select_values(arel, name = nil)
      arel, binds = binds_from_relation arel, []
      select_rows(to_sql(arel, binds), name, binds).map(&:first)
    end

supports_statement_cache?() click to toggle source

Returns `true` when the connection adapter supports prepared statement caching, otherwise returns `false`

    # File lib/active_record/connection_adapters/abstract/database_statements.rb, line 124
    def supports_statement_cache?
      false
    end

to_sql(arel, binds = []) click to toggle source

Converts an arel AST to SQL

    # File lib/active_record/connection_adapters/abstract/database_statements.rb, line 10
    def to_sql(arel, binds = [])
      if arel.respond_to?(:ast)
        collected = visitor.accept(arel.ast, collector)
        collected.compile(binds.dup, self)
      else
        arel
      end
    end

transaction(options = {}) { || ... } click to toggle source

Runs the given block in a database transaction, and returns the result of the block.

## Nested transactions support¶ ↑

Most databases don't support true nested transactions. At the time of writing, the only database that supports true nested transactions that we're aware of, is MS-SQL.

In order to get around this problem, transaction will emulate the effect of nested transactions, by using savepoints: dev.mysql.com/doc/refman/5.0/en/savepoint.html Savepoints are supported by MySQL and PostgreSQL. SQLite3 version >= '3.6.8' supports savepoints.

It is safe to call this method if a database transaction is already open, i.e. if transaction is called within another transaction block. In case of a nested call, transaction will behave as follows:

- The block will be run without doing anything. All database statements that happen within the block are effectively appended to the already open database transaction.

- However, if `:requires_new` is set, the block will be wrapped in a database savepoint acting as a sub-transaction.

### Caveats¶ ↑

MySQL doesn't support DDL transactions. If you perform a DDL operation, then any created savepoints will be automatically released. For example, if you've created a savepoint, then you execute a CREATE TABLE statement, then the savepoint that was created will be automatically released.

This means that, on MySQL, you shouldn't execute DDL operations inside a transaction call that you know might create a savepoint. Otherwise, transaction will raise exceptions when it tries to release the already-automatically-released savepoints:

    Model.connection.transaction do  # BEGIN
      Model.connection.transaction(requires_new: true) do  # CREATE SAVEPOINT active_record_1
        Model.connection.create_table(...)
        # active_record_1 now automatically released
      end  # RELEASE SAVEPOINT active_record_1  <--- BOOM! database error!
    end

## Transaction isolation¶ ↑

If your database supports setting the isolation level for a transaction, you can set it like so:

    Post.transaction(isolation: :serializable) do
      # ...
    end

Valid isolation levels are:

- `:read_uncommitted`

- `:read_committed`

- `:repeatable_read`

- `:serializable`

You should consult the documentation for your database to understand the semantics of these different levels:

- www.postgresql.org/docs/9.1/static/transaction-iso.html

- dev.mysql.com/doc/refman/5.0/en/set-transaction.html

An `ActiveRecord::TransactionIsolationError` will be raised if:

- The adapter does not support setting the isolation level

- You are joining an existing open transaction

- You are creating a nested (savepoint) transaction

The mysql, mysql2 and postgresql adapters support setting the transaction isolation level. However, support is disabled for MySQL versions below 5, because they are affected by a bug which means the isolation level gets persisted outside the transaction.

    # File lib/active_record/connection_adapters/abstract/database_statements.rb, line 204
    def transaction(options = {})
      options.assert_valid_keys :requires_new, :joinable, :isolation

      if !options[:requires_new] && current_transaction.joinable?
        if options[:isolation]
          raise ActiveRecord::TransactionIsolationError, "cannot set isolation when joining a transaction"
        end
        yield
      else
        transaction_manager.within_new_transaction(options) { yield }
      end
    rescue ActiveRecord::Rollback
      # rollbacks are silently swallowed
    end

transaction_isolation_levels() click to toggle source

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

transaction_open?() click to toggle source

    # File lib/active_record/connection_adapters/abstract/database_statements.rb, line 223
    def transaction_open?
      current_transaction.open?
    end

transaction_state() click to toggle source

    # File lib/active_record/connection_adapters/abstract/database_statements.rb, line 237
    def transaction_state
      current_transaction.state
    end

truncate(table_name, name = nil) click to toggle source

Executes the truncate statement.

    # File lib/active_record/connection_adapters/abstract/database_statements.rb, line 87
    def truncate(table_name, name = nil)
      raise NotImplementedError
    end

update(arel, name = nil, binds = []) click to toggle source

Executes the update statement and returns the number of rows affected.

    # File lib/active_record/connection_adapters/abstract/database_statements.rb, line 113
    def update(arel, name = nil, binds = [])
      exec_update(to_sql(arel, binds), name, binds)
    end