Class: DataMapper::Transaction

### Home Classes Methods

### In Files

- lib/dm-transactions.rb
- lib/dm-transactions/adapters/dm-do-adapter.rb
- lib/dm-transactions/adapters/dm-mysql-adapter.rb
- lib/dm-transactions/adapters/dm-oracle-adapter.rb
- lib/dm-transactions/adapters/dm-postgres-adapter.rb
- lib/dm-transactions/adapters/dm-sqlite-adapter.rb
- lib/dm-transactions/adapters/dm-sqlserver-adapter.rb

### Parent

Object

### Namespace

- MODULE DataMapper::Transaction::DataObjectsAdapter
- MODULE DataMapper::Transaction::Model
- MODULE DataMapper::Transaction::MysqlAdapter
- MODULE DataMapper::Transaction::OracleAdapter
- MODULE DataMapper::Transaction::PostgresAdapter
- MODULE DataMapper::Transaction::Repository
- MODULE DataMapper::Transaction::Resource
- MODULE DataMapper::Transaction::SqliteAdapter
- MODULE DataMapper::Transaction::SqlserverAdapter

### Methods

- ::new
- #begin
- #begin?
- #commit
- #commit?
- #link
- #method_missing
- #none?
- #primitive_for
- #rollback
- #rollback?
- #within

### Files

- LICENSE
- README.rdoc

### Class/Module Index

Quicksearch

- DataMapper
- DataMapper::Adapters
- DataMapper::Transaction
- DataMapper::Transaction::DataObjectsAdapter
- DataMapper::Transaction::Model
- DataMapper::Transaction::MysqlAdapter
- DataMapper::Transaction::OracleAdapter
- DataMapper::Transaction::PostgresAdapter
- DataMapper::Transaction::Repository
- DataMapper::Transaction::Resource
- DataMapper::Transaction::SqliteAdapter
- DataMapper::Transaction::SqlserverAdapter

No matching classes.

# DataMapper::Transaction

### Attributes

state[RW]

@api private

### Public Class Methods

new(*things) click to toggle source

Create a new Transaction

@see Transaction#link

In fact, it just calls link with the given arguments at the end of the constructor.

@api public

    # File lib/dm-transactions.rb, line 38
    def initialize(*things)
      @transaction_primitives = {}
      self.state = :none
      @adapters = {}
      link(*things)
      if block_given?
        warn "Passing block to #{self.class.name}.new is deprecated (#{caller[0]})"
        commit { |*block_args| yield(*block_args) }
      end
    end

### Public Instance Methods

begin() click to toggle source

Begin the transaction

Before begin is called, the transaction is not valid and can not be used.

@api private

    # File lib/dm-transactions.rb, line 103
    def begin
      unless none?
        raise "Illegal state for begin: #{state}"
      end

      each_adapter(:connect_adapter, [:log_fatal_transaction_breakage])
      each_adapter(:begin_adapter, [:rollback_and_close_adapter_if_begin, :close_adapter_if_none])
      self.state = :begin
    end

begin?() click to toggle source

@api private

    # File lib/dm-transactions.rb, line 16
    def begin?
      state == :begin
    end

commit() click to toggle source

Commit the transaction

    If no block is given, it will simply commit any changes made since the
    Transaction did #begin.

@param block<Block> a block (taking the one argument, the Transaction) to

    execute within this transaction. The transaction will begin and commit
    around the block, and roll back if an exception is raised.

@api private

    # File lib/dm-transactions.rb, line 123
    def commit
      if block_given?
        unless none?
          raise "Illegal state for commit with block: #{state}"
        end

        begin
          self.begin
          rval = within { |*block_args| yield(*block_args) }
        rescue Exception => exception
          if begin?
            rollback
          end
          raise exception
        ensure
          unless exception
            if begin?
              commit
            end
            return rval
          end
        end
      else
        unless begin?
          raise "Illegal state for commit without block: #{state}"
        end
        each_adapter(:commit_adapter, [:log_fatal_transaction_breakage])
        each_adapter(:close_adapter, [:log_fatal_transaction_breakage])
        self.state = :commit
      end
    end

commit?() click to toggle source

@api private

    # File lib/dm-transactions.rb, line 26
    def commit?
      state == :commit
    end

link(*things) click to toggle source

Associate this Transaction with some things.

@param [Object] things

    the things you want this Transaction associated with:

    Adapters::AbstractAdapter subclasses will be added as
      adapters as is.
    Arrays will have their elements added.
    Repository will have it's own @adapters added.
    Resource subclasses will have all the repositories of all
      their properties added.
    Resource instances will have all repositories of all their
      properties added.

@param [Proc] block

    a block (taking one argument, the Transaction) to execute within
    this transaction. The transaction will begin and commit around
    the block, and rollback if an exception is raised.

@api private

    # File lib/dm-transactions.rb, line 69
    def link(*things)
      unless none?
        raise "Illegal state for link: #{state}"
      end

      things.each do |thing|
        case thing
          when DataMapper::Adapters::AbstractAdapter
            @adapters[thing] = :none
          when DataMapper::Repository
            link(thing.adapter)
          when DataMapper::Model
            link(*thing.repositories)
          when DataMapper::Resource
            link(thing.model)
          when Array
            link(*thing)
          else
            raise "Unknown argument to #{self.class}#link: #{thing.inspect} (#{thing.class})"
        end
      end

      if block_given?
        commit { |*block_args| yield(*block_args) }
      else
        self
      end
    end

method_missing(method, *args, &block) click to toggle source

@api private

    # File lib/dm-transactions.rb, line 204
    def method_missing(method, *args, &block)
      first_arg = args.first

      return super unless args.size == 1 && first_arg.kind_of?(Adapters::AbstractAdapter)
      return super unless match = method.to_s.match(/\A(.*)_(if|unless)_(none|begin|rollback|commit)\z/)

      action, condition, expected_state = match.captures
      return super unless respond_to?(action, true)

      state   = state_for(first_arg).to_s
      execute = (condition == 'if') == (state == expected_state)

      send(action, first_arg) if execute
    end

none?() click to toggle source

@api private

    # File lib/dm-transactions.rb, line 11
    def none?
      state == :none
    end

primitive_for(adapter) click to toggle source

@api private

    # File lib/dm-transactions.rb, line 220
    def primitive_for(adapter)
      unless @adapters.include?(adapter)
        raise "Unknown adapter #{adapter}"
      end

      unless @transaction_primitives.include?(adapter)
        raise "No primitive for #{adapter}"
      end

      @transaction_primitives[adapter]
    end

rollback() click to toggle source

Rollback the transaction

Will undo all changes made during the transaction.

@api private

    # File lib/dm-transactions.rb, line 160
    def rollback
      unless begin?
        raise "Illegal state for rollback: #{state}"
      end
      each_adapter(:rollback_adapter_if_begin, [:rollback_and_close_adapter_if_begin, :close_adapter_if_none])
      each_adapter(:close_adapter_if_open, [:log_fatal_transaction_breakage])
      self.state = :rollback
    end

rollback?() click to toggle source

@api private

    # File lib/dm-transactions.rb, line 21
    def rollback?
      state == :rollback
    end

within() click to toggle source

Execute a block within this Transaction.

No begin, commit or rollback is performed in within, but this Transaction will pushed on the per thread stack of transactions for each adapter it is associated with, and it will ensures that it will pop the Transaction away again after the block is finished.

@param block<Block> the block of code to execute.

@api private

    # File lib/dm-transactions.rb, line 179
    def within
      unless block_given?
        raise 'No block provided'
      end

      unless begin?
        raise "Illegal state for within: #{state}"
      end

      adapters = @adapters

      adapters.each_key do |adapter|
        adapter.push_transaction(self)
      end

      begin
        yield self
      ensure
        adapters.each_key do |adapter|
          adapter.pop_transaction
        end
      end
    end

[Validate]

Generated with the Darkfish Rdoc Generator 2.