Skip to content

Commit

Permalink
Merge branch 'transactions' of https://github.com/AlfonsoUceda/model
Browse files Browse the repository at this point in the history
…into AlfonsoUceda-transactions
  • Loading branch information
jodosha committed Jan 19, 2015
2 parents 44254ae + 158c1b7 commit 2901716
Show file tree
Hide file tree
Showing 4 changed files with 168 additions and 0 deletions.
12 changes: 12 additions & 0 deletions lib/lotus/model/adapters/abstract.rb
Expand Up @@ -162,6 +162,18 @@ def command(query)
def query(collection, &blk)
raise NotImplementedError
end

# Create a transaction
# Only supported by SqlAdapter
#
# @param options [Hash] options for transaction
#
# @see Lotus::Model::Adapters::SqlAdapter#transaction
#
# @since x.x.x
def transaction(options = {})
yield
end
end
end
end
Expand Down
14 changes: 14 additions & 0 deletions lib/lotus/model/adapters/sql_adapter.rb
Expand Up @@ -132,6 +132,20 @@ def query(collection, context = nil, &blk)
Sql::Query.new(_collection(collection), context, &blk)
end

# Create a transaction
#
# @param options [Hash] options for transaction
#
# @see http://sequel.jeremyevans.net/rdoc/files/doc/transactions_rdoc.html
#
# @api private
# @since x.x.x
def transaction(options = {})
@connection.transaction(options) do
yield
end
end

private

# Returns a collection from the given name.
Expand Down
69 changes: 69 additions & 0 deletions lib/lotus/repository.rb
Expand Up @@ -505,6 +505,75 @@ def clear
@adapter.clear(collection)
end

# Create a transaction
#
# @param options [Hash] options for transaction
#
# @see Lotus::Model::Adapters::SqlAdapter#transaction
#
# @since x.x.x
#
# @example
# require 'lotus/model'
#
# class Article
# include Lotus::Entity
# attributes :title, :body
# end
#
# class ArticleRepository
# include Lotus::Repository
# end
#
# article = Article.new title: 'Introducing transactions', body: 'lorem ipsum'
#
# ArticleRepository.transaction do
# ArticleRepository.create(article)
# end
#
# @example
# require 'lotus/model'
#
# class Article
# include Lotus::Entity
# attributes :title, :body
# end
#
# class ArticleRepository
# include Lotus::Repository
# end
#
# article = Article.new title: 'Introducing transactions', body: 'lorem ipsum'
#
# ArticleRepository.transaction(rollback: :always) do
# ArticleRepository.create(article)
# end # ROLLBACK
# # no exception raised
#
# @example
# require 'lotus/model'
#
# class Article
# include Lotus::Entity
# attributes :title, :body
# end
#
# class ArticleRepository
# include Lotus::Repository
# end
#
# article = Article.new title: 'Introducing transactions', body: 'lorem ipsum'
#
# ArticleRepository.transaction(rollback: :reraise) do
# raise Exception
# end # ROLLBACK
# # Exception raised
def transaction(options = {})
@adapter.transaction(options) do
yield
end
end

private
# Fabricates a query and yields the given block to access the low level
# APIs exposed by the query itself.
Expand Down
73 changes: 73 additions & 0 deletions test/repository_test.rb
Expand Up @@ -316,4 +316,77 @@ def to_int
end
end
end

describe "with sql adapter" do
before do
UserRepository.adapter = Lotus::Model::Adapters::SqlAdapter.new(MAPPER, SQLITE_CONNECTION_STRING)
ArticleRepository.adapter = Lotus::Model::Adapters::SqlAdapter.new(MAPPER, SQLITE_CONNECTION_STRING)

UserRepository.collection = :users
ArticleRepository.collection = :articles

UserRepository.clear
ArticleRepository.clear

ArticleRepository.create(article1)
end

describe '.transaction' do
it 'if an exception is raised the size of articles is equal to 1' do
ArticleRepository.all.size.must_equal 1
exception = -> { ArticleRepository.transaction do
ArticleRepository.create(article2)
raise Exception
end }
exception.must_raise Exception
ArticleRepository.all.size.must_equal 1
end

it "if an exception isn't raised the size of articles is equal to 2" do
ArticleRepository.all.size.must_equal 1
ArticleRepository.transaction do
ArticleRepository.create(article2)
end
ArticleRepository.all.size.must_equal 2
end

describe 'using options' do
it 'rollback: :always option' do
ArticleRepository.all.size.must_equal 1
ArticleRepository.transaction(rollback: :always) do
ArticleRepository.create(article2)
end
ArticleRepository.all.size.must_equal 1
end

it 'rollback: :reraise option' do
ArticleRepository.all.size.must_equal 1
-> { ArticleRepository.transaction(rollback: :reraise) do
raise Exception
end }.must_raise Exception
end
end
end
end

describe "with memory adapter" do
before do
UserRepository.adapter = Lotus::Model::Adapters::MemoryAdapter.new(MAPPER, nil)
ArticleRepository.adapter = Lotus::Model::Adapters::MemoryAdapter.new(MAPPER, nil)

UserRepository.collection = :users
ArticleRepository.collection = :articles

UserRepository.clear
ArticleRepository.clear
end

describe '.transaction' do
it "an exception is raised because of memory adapter doesn't support transactions" do
-> { ArticleRepository.transaction do
raise "boom"
end }.must_raise RuntimeError
end
end
end
end

0 comments on commit 2901716

Please sign in to comment.