up_and_at_them 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: e2a05a7454d62421c8d4029dbae49370ddbaf695
4
+ data.tar.gz: ecdfc5d2c6d0831bb9c7486392635509a821b578
5
+ SHA512:
6
+ metadata.gz: 26ed6944e975a43fbfebf3596d37ed82331e3b98907f30100ebdba42dd745f4f34921c2499ea2ec66b90e61e29de29de157833a79ffb272c84dbc12026c9cce1
7
+ data.tar.gz: 82880cc5008cdb448964596eda8077bf8fafcdbe3f4093714eb28e2872bb6920479ec7e4d6465f25ecd72b87d2b2bc14521bdab62db687696788347d4fb6228c
data/.gitignore ADDED
@@ -0,0 +1,22 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ *.bundle
19
+ *.so
20
+ *.o
21
+ *.a
22
+ mkmf.log
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in up_and_at_them.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,16 @@
1
+ Copyright 2014 Metova, Inc.
2
+
3
+ This product includes software developed at
4
+ Metova, Inc. (http://www.metova.com/).
5
+
6
+ Licensed under the Apache License, Version 2.0 (the "License");
7
+ you may not use this file except in compliance with the License.
8
+ You may obtain a copy of the License at
9
+
10
+ http://www.apache.org/licenses/LICENSE-2.0
11
+
12
+ Unless required by applicable law or agreed to in writing, software
13
+ distributed under the License is distributed on an "AS IS" BASIS,
14
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ See the License for the specific language governing permissions and
16
+ limitations under the License.
data/README.md ADDED
@@ -0,0 +1,41 @@
1
+ # Up And At Them!
2
+
3
+ [![Up And At Them!](http://img.youtube.com/vi/457nGTf4fsQ/0.jpg)](http://www.youtube.com/watch?v=457nGTf4fsQ)
4
+
5
+ This gem provides a method for performing atomic transactions with the capability to rollback. Note that this is for
6
+ any general Ruby operation and does not replace
7
+ [ActiveRecord::Rollback](http://api.rubyonrails.org/classes/ActiveRecord/Rollback.html).
8
+
9
+ ## Installation
10
+
11
+ Add this line to your application's Gemfile:
12
+
13
+ gem 'up_and_at_them'
14
+
15
+ And then execute:
16
+
17
+ $ bundle
18
+
19
+ Or install it yourself as:
20
+
21
+ $ gem install up_and_at_them
22
+
23
+ ## Usage
24
+
25
+ Create a Transaction which contains all of your commits. Note that the Transaction will run as soon as it is
26
+ initialized.
27
+
28
+ UpAndAtThem::Transaction.new([
29
+ UpAndAtThem::Commit.new { puts "do something!" }.on_rollback { "undo something!" },
30
+ UpAndAtThem::Commit.new { puts "do something else!" }.on_rollback { "undo something else!" },
31
+ ])
32
+
33
+ See the tests for other example Commit actions within a Transaction.
34
+
35
+ ## Contributing
36
+
37
+ 1. Fork it ( https://github.com/metova/up_and_at_them/fork )
38
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
39
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
40
+ 4. Push to the branch (`git push origin my-new-feature`)
41
+ 5. Create a new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ require "bundler/gem_tasks"
2
+
@@ -0,0 +1,3 @@
1
+ module UpAndAtThem
2
+ VERSION = "0.0.2"
3
+ end
@@ -0,0 +1,47 @@
1
+ require "up_and_at_them/version"
2
+
3
+ module UpAndAtThem
4
+ class Commit
5
+ def initialize(&block)
6
+ raise LocalJumpError unless block_given?
7
+ @block = block
8
+ end
9
+ def on_rollback(&block)
10
+ raise LocalJumpError unless block_given?
11
+ @rollback = block
12
+ self
13
+ end
14
+ def call
15
+ @block.call
16
+ end
17
+ def rollback
18
+ @rollback.call if @rollback
19
+ end
20
+ end
21
+
22
+ class Transaction
23
+ def initialize(tasks)
24
+ tasks = Array(tasks)
25
+ tasks.each do |t|
26
+ Commit === t or raise TypeError
27
+ end
28
+ @tasks = tasks
29
+ run
30
+ end
31
+
32
+ def run
33
+ finished_tasks = []
34
+ begin
35
+ @tasks.each do |task|
36
+ task.call
37
+ finished_tasks << task
38
+ end
39
+ rescue => err
40
+ finished_tasks.reverse_each do |task|
41
+ task.rollback
42
+ end
43
+ raise err
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,54 @@
1
+ require 'minitest/autorun'
2
+ require 'up_and_at_them'
3
+
4
+ class TransactionTest < MiniTest::Test
5
+ def test_rollback_past_commits
6
+ flags = {1 => :pending, 2 => :pending, 3 => :pending, 4 => :pending}
7
+
8
+ commits = Array.new
9
+ (1...4).each do |i|
10
+ commits << UpAndAtThem::Commit.new { flags[i] = :committed; if i==3 ; raise 'uh oh!'; end }.on_rollback { flags[i] = :rolled_back }
11
+ end
12
+
13
+ assert_raises RuntimeError do
14
+ UpAndAtThem::Transaction.new commits
15
+ end
16
+ assert_equal :pending, flags[4]
17
+ assert_equal :committed, flags[3]
18
+ assert_equal :rolled_back, flags[2]
19
+ assert_equal :rolled_back, flags[1]
20
+ end
21
+
22
+ def test_rollback_in_reverse_commit_order
23
+ flags = {1 => -1, 2 => -1, 3 => -1, 4 => -1}
24
+
25
+ commits = Array.new
26
+ (1...4).each do |i|
27
+ commits << UpAndAtThem::Commit.new { flags[i] = -1; if i==3 ; raise 'uh oh!'; end }.on_rollback { flags[i] = Time.now; sleep 1 }
28
+ end
29
+
30
+ assert_raises RuntimeError do
31
+ UpAndAtThem::Transaction.new commits
32
+ end
33
+ assert_equal -1, flags[4]
34
+ assert flags[3].to_f < flags[2].to_f
35
+ assert flags[2].to_f < flags[1].to_f
36
+ end
37
+
38
+ def test_allow_no_rollback_blocks
39
+ flags = {1 => :pending, 2 => :pending, 3 => :pending, 4 => :pending}
40
+
41
+ commits = Array.new
42
+ (1...4).each do |i|
43
+ commits << UpAndAtThem::Commit.new { flags[i] = :committed; if i==3 ; raise 'fail!'; end }
44
+ end
45
+
46
+ assert_raises RuntimeError do
47
+ UpAndAtThem::Transaction.new commits
48
+ end
49
+ assert_equal :pending, flags[4]
50
+ assert_equal :committed, flags[3]
51
+ assert_equal :committed, flags[2]
52
+ assert_equal :committed, flags[1]
53
+ end
54
+ end
@@ -0,0 +1,23 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'up_and_at_them/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "up_and_at_them"
8
+ spec.version = UpAndAtThem::VERSION
9
+ spec.authors = ["Dave Lane"]
10
+ spec.email = ["dave.lane@metova.com"]
11
+ spec.summary = 'A library for simplifying atomic transactions.'
12
+ spec.description = 'A library for simplifying atomic transactions with the option for rollback of each operation in the transaction.'
13
+ spec.homepage = "http://github.com/metova/up_and_at_them"
14
+ spec.license = "Apache"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_development_dependency "bundler", "~> 1.6"
22
+ spec.add_development_dependency "rake"
23
+ end
metadata ADDED
@@ -0,0 +1,83 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: up_and_at_them
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.2
5
+ platform: ruby
6
+ authors:
7
+ - Dave Lane
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-10-07 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.6'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.6'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ description: A library for simplifying atomic transactions with the option for rollback
42
+ of each operation in the transaction.
43
+ email:
44
+ - dave.lane@metova.com
45
+ executables: []
46
+ extensions: []
47
+ extra_rdoc_files: []
48
+ files:
49
+ - ".gitignore"
50
+ - Gemfile
51
+ - LICENSE.txt
52
+ - README.md
53
+ - Rakefile
54
+ - lib/up_and_at_them.rb
55
+ - lib/up_and_at_them/version.rb
56
+ - test/test_transaction.rb
57
+ - up_and_at_them.gemspec
58
+ homepage: http://github.com/metova/up_and_at_them
59
+ licenses:
60
+ - Apache
61
+ metadata: {}
62
+ post_install_message:
63
+ rdoc_options: []
64
+ require_paths:
65
+ - lib
66
+ required_ruby_version: !ruby/object:Gem::Requirement
67
+ requirements:
68
+ - - ">="
69
+ - !ruby/object:Gem::Version
70
+ version: '0'
71
+ required_rubygems_version: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ requirements: []
77
+ rubyforge_project:
78
+ rubygems_version: 2.2.0
79
+ signing_key:
80
+ specification_version: 4
81
+ summary: A library for simplifying atomic transactions.
82
+ test_files:
83
+ - test/test_transaction.rb