lev 1.0.1 → 2.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile.lock +3 -1
- data/lev.gemspec +1 -0
- data/lib/lev.rb +3 -0
- data/lib/lev/handler.rb +3 -3
- data/lib/lev/object.rb +25 -0
- data/lib/lev/outputs.rb +39 -0
- data/lib/lev/routine.rb +20 -19
- data/lib/lev/version.rb +1 -1
- data/spec/outputs_spec.rb +80 -0
- data/spec/support/create_sprocket.rb +1 -1
- metadata +23 -3
data/Gemfile.lock
CHANGED
@@ -1,11 +1,12 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
lev (
|
4
|
+
lev (2.0.1)
|
5
5
|
actionpack (>= 3.0)
|
6
6
|
active_attr
|
7
7
|
activemodel (>= 3.0)
|
8
8
|
activerecord (>= 3.0)
|
9
|
+
hashie
|
9
10
|
transaction_isolation
|
10
11
|
transaction_retry
|
11
12
|
|
@@ -48,6 +49,7 @@ GEM
|
|
48
49
|
debugger-ruby_core_source (1.2.3)
|
49
50
|
diff-lcs (1.2.4)
|
50
51
|
erubis (2.7.0)
|
52
|
+
hashie (2.0.5)
|
51
53
|
i18n (0.6.5)
|
52
54
|
minitest (4.7.5)
|
53
55
|
multi_json (1.8.0)
|
data/lev.gemspec
CHANGED
@@ -24,6 +24,7 @@ Gem::Specification.new do |spec|
|
|
24
24
|
spec.add_runtime_dependency "transaction_isolation"
|
25
25
|
spec.add_runtime_dependency "transaction_retry"
|
26
26
|
spec.add_runtime_dependency "active_attr"
|
27
|
+
spec.add_runtime_dependency "hashie"
|
27
28
|
|
28
29
|
spec.add_development_dependency "bundler", "~> 1.3"
|
29
30
|
spec.add_development_dependency "rake"
|
data/lib/lev.rb
CHANGED
@@ -2,12 +2,15 @@ require "action_view"
|
|
2
2
|
require "transaction_isolation"
|
3
3
|
require "transaction_retry"
|
4
4
|
require "active_attr"
|
5
|
+
require "hashie"
|
5
6
|
|
6
7
|
require "lev/version"
|
8
|
+
require "lev/object"
|
7
9
|
require "lev/utilities"
|
8
10
|
require "lev/exceptions"
|
9
11
|
require "lev/better_active_model_errors"
|
10
12
|
require "lev/term_mapper"
|
13
|
+
require "lev/outputs"
|
11
14
|
require "lev/routine"
|
12
15
|
require "lev/handler"
|
13
16
|
require "lev/handle_with"
|
data/lib/lev/handler.rb
CHANGED
@@ -13,7 +13,7 @@ module Lev
|
|
13
13
|
# doing something with it. See Lev::Routine for more information.
|
14
14
|
#
|
15
15
|
# All handlers must:
|
16
|
-
# 2)
|
16
|
+
# 2) call "lev_handler"
|
17
17
|
# 3) implement the 'handle' method which takes no arguments and does the
|
18
18
|
# work the handler is charged with
|
19
19
|
# 4) implement the 'authorized?' method which returns true iff the
|
@@ -32,7 +32,7 @@ module Lev
|
|
32
32
|
# the Handler class would look like:
|
33
33
|
#
|
34
34
|
# class MyHandler
|
35
|
-
#
|
35
|
+
# lev_handler
|
36
36
|
#
|
37
37
|
# paramify :search do
|
38
38
|
# attribute :search_type, type: String
|
@@ -88,7 +88,7 @@ module Lev
|
|
88
88
|
# Example:
|
89
89
|
#
|
90
90
|
# class MyHandler
|
91
|
-
#
|
91
|
+
# lev_handler
|
92
92
|
# protected
|
93
93
|
# def authorized?
|
94
94
|
# # return true iff exec is allowed to be called, e.g. might
|
data/lib/lev/object.rb
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
class Object
|
2
|
+
|
3
|
+
def self.lev_routine(options={})
|
4
|
+
class_eval do
|
5
|
+
include Lev::Routine unless options[:skip_routine_include]
|
6
|
+
|
7
|
+
# Routine configuration
|
8
|
+
options[:transaction] ||= Lev::TransactionIsolation.mysql_default.symbol
|
9
|
+
@transaction_isolation = Lev::TransactionIsolation.new(options[:transaction])
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.lev_handler(options={})
|
14
|
+
class_eval do
|
15
|
+
include Lev::Handler
|
16
|
+
end
|
17
|
+
|
18
|
+
# Do routine configuration
|
19
|
+
options[:skip_routine_include] = true
|
20
|
+
lev_routine(options)
|
21
|
+
|
22
|
+
# Do handler configuration (none currently)
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
data/lib/lev/outputs.rb
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
module Lev
|
2
|
+
class Outputs < Hashie::Mash
|
3
|
+
|
4
|
+
def initialize(source_hash = nil, default = nil, &blk)
|
5
|
+
@array_created = {}
|
6
|
+
super(source_hash, default, &blk)
|
7
|
+
end
|
8
|
+
|
9
|
+
def add(name, value)
|
10
|
+
if self[name].nil?
|
11
|
+
self[name] = value
|
12
|
+
elsif @array_created[name]
|
13
|
+
self[name].push value
|
14
|
+
else
|
15
|
+
@array_created[name] = true
|
16
|
+
self[name] = [self[name], value]
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def each
|
21
|
+
self.each_key do |key|
|
22
|
+
key = key.to_sym
|
23
|
+
if @array_created[key]
|
24
|
+
self[key].each { |value| yield key, value }
|
25
|
+
else
|
26
|
+
yield key, self[key]
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def transfer_to(other_outputs, &name_mapping_block)
|
32
|
+
self.each do |name, value|
|
33
|
+
new_name = block_given? ? name_mapping_block.call(name) : name
|
34
|
+
other_outputs.add(new_name, value)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
end
|
data/lib/lev/routine.rb
CHANGED
@@ -18,7 +18,7 @@ module Lev
|
|
18
18
|
#
|
19
19
|
# A class becomes a routine by adding:
|
20
20
|
#
|
21
|
-
#
|
21
|
+
# lev_routine
|
22
22
|
#
|
23
23
|
# in its definition.
|
24
24
|
#
|
@@ -36,9 +36,19 @@ module Lev
|
|
36
36
|
# routines aren't typically instantiated with state).
|
37
37
|
#
|
38
38
|
# A routine is automatically run within a transaction. The isolation level
|
39
|
-
# of the routine can be set by
|
40
|
-
#
|
41
|
-
#
|
39
|
+
# of the routine can be set by passing a :transaction option to the lev_routine
|
40
|
+
# call (or to the lev_handler call, if appropriate). The value must be one of
|
41
|
+
#
|
42
|
+
# :no_transaction
|
43
|
+
# :read_uncommitted
|
44
|
+
# :read_committed
|
45
|
+
# :repeatable_read
|
46
|
+
# :serializable
|
47
|
+
#
|
48
|
+
# e.g.
|
49
|
+
#
|
50
|
+
# class MyRoutine
|
51
|
+
# lev_routine transaction: :no_transaction
|
42
52
|
#
|
43
53
|
# As mentioned above, routines can call other routines. While this is of
|
44
54
|
# course possible just by calling the other routine's call method directly,
|
@@ -91,7 +101,7 @@ module Lev
|
|
91
101
|
# context. E.g., in the following class:
|
92
102
|
#
|
93
103
|
# class Routine1
|
94
|
-
#
|
104
|
+
# lev_routine
|
95
105
|
# uses_routine Routine2,
|
96
106
|
# translations: {
|
97
107
|
# inputs: { map: {bar: :foo} }
|
@@ -176,14 +186,9 @@ module Lev
|
|
176
186
|
attr_reader :errors
|
177
187
|
|
178
188
|
def initialize
|
179
|
-
@outputs =
|
189
|
+
@outputs = Outputs.new
|
180
190
|
@errors = Errors.new
|
181
191
|
end
|
182
|
-
|
183
|
-
def add_output(name, value)
|
184
|
-
outputs[name] = [outputs[name], value].flatten.compact
|
185
|
-
outputs[name] = outputs[name].first if outputs[name].size == 1
|
186
|
-
end
|
187
192
|
end
|
188
193
|
|
189
194
|
def self.included(base)
|
@@ -213,11 +218,7 @@ module Lev
|
|
213
218
|
end
|
214
219
|
|
215
220
|
def transaction_isolation
|
216
|
-
@transaction_isolation ||=
|
217
|
-
end
|
218
|
-
|
219
|
-
def default_transaction_isolation
|
220
|
-
TransactionIsolation.mysql_default
|
221
|
+
@transaction_isolation ||= TransactionIsolation.mysql_default
|
221
222
|
end
|
222
223
|
|
223
224
|
def nested_routines
|
@@ -323,8 +324,8 @@ module Lev
|
|
323
324
|
options[:errors_are_fatal] = true if !options.has_key?(:errors_are_fatal)
|
324
325
|
transfer_errors_from(run_result.errors, input_mapper, options[:errors_are_fatal])
|
325
326
|
|
326
|
-
run_result.outputs.
|
327
|
-
|
327
|
+
run_result.outputs.transfer_to(outputs) do |name|
|
328
|
+
output_mapper.map(name)
|
328
329
|
end
|
329
330
|
|
330
331
|
run_result
|
@@ -380,7 +381,7 @@ module Lev
|
|
380
381
|
def runner=(runner)
|
381
382
|
@runner = runner
|
382
383
|
|
383
|
-
if topmost_runner.class.transaction_isolation.weaker_than(self.class.
|
384
|
+
if topmost_runner.class.transaction_isolation.weaker_than(self.class.transaction_isolation)
|
384
385
|
raise IsolationMismatch,
|
385
386
|
"The routine being run has a stronger isolation requirement than " +
|
386
387
|
"the isolation being used by the routine(s) running it; call the " +
|
data/lib/lev/version.rb
CHANGED
@@ -0,0 +1,80 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Lev::Outputs do
|
4
|
+
|
5
|
+
let(:outputs) { Lev::Outputs.new }
|
6
|
+
|
7
|
+
it "should return a non-array when given just one non-array" do
|
8
|
+
outputs.add(:x, 4)
|
9
|
+
expect(outputs[:x]).to eq 4
|
10
|
+
end
|
11
|
+
|
12
|
+
it "should return an array when given just one array" do
|
13
|
+
outputs.add(:x, [1,2])
|
14
|
+
expect(outputs[:x]).to eq [1,2]
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should work when given a non-array and an array" do
|
18
|
+
outputs.add(:x, 4)
|
19
|
+
outputs.add(:x, [1,2])
|
20
|
+
expect(outputs[:x]).to eq [4, [1,2]]
|
21
|
+
end
|
22
|
+
|
23
|
+
it "should work when given two or three non-arrays" do
|
24
|
+
outputs.add(:x, 1)
|
25
|
+
outputs.add(:x, 2)
|
26
|
+
expect(outputs.x).to eq [1,2]
|
27
|
+
outputs.add(:x, 3)
|
28
|
+
expect(outputs.x).to eq [1,2,3]
|
29
|
+
end
|
30
|
+
|
31
|
+
it "should work when given a mix" do
|
32
|
+
outputs.add(:x, [3,4])
|
33
|
+
outputs.add(:x, "hi")
|
34
|
+
outputs.add(:x, {a: 2})
|
35
|
+
expect(outputs.x).to eq [[3,4], "hi", {a: 2}]
|
36
|
+
end
|
37
|
+
|
38
|
+
it "should transfer well" do
|
39
|
+
outputs.add(:x, 4)
|
40
|
+
outputs.add(:x, 5)
|
41
|
+
|
42
|
+
other_outputs = Lev::Outputs.new
|
43
|
+
|
44
|
+
outputs.each do |name, value|
|
45
|
+
other_outputs.add(name, value)
|
46
|
+
end
|
47
|
+
|
48
|
+
other_outputs.add(:x, 6)
|
49
|
+
|
50
|
+
expect(other_outputs.x).to eq [4,5,6]
|
51
|
+
end
|
52
|
+
|
53
|
+
it "should work via transfer_to with name mapping" do
|
54
|
+
outputs.add(:x, 4)
|
55
|
+
outputs.add(:x, 5)
|
56
|
+
|
57
|
+
other_outputs = Lev::Outputs.new
|
58
|
+
|
59
|
+
outputs.transfer_to(other_outputs) do |name|
|
60
|
+
:y
|
61
|
+
end
|
62
|
+
|
63
|
+
other_outputs.add(:y, 6)
|
64
|
+
expect(other_outputs.y).to eq [4,5,6]
|
65
|
+
end
|
66
|
+
|
67
|
+
it "should work via transfer_to without name mapping" do
|
68
|
+
outputs.add(:x, 4)
|
69
|
+
outputs.add(:x, 5)
|
70
|
+
|
71
|
+
other_outputs = Lev::Outputs.new
|
72
|
+
|
73
|
+
outputs.transfer_to(other_outputs)
|
74
|
+
|
75
|
+
other_outputs.add(:y, 6)
|
76
|
+
expect(other_outputs.x).to eq [4,5]
|
77
|
+
expect(other_outputs.y).to eq 6
|
78
|
+
end
|
79
|
+
|
80
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: lev
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 2.0.1
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -107,6 +107,22 @@ dependencies:
|
|
107
107
|
- - ! '>='
|
108
108
|
- !ruby/object:Gem::Version
|
109
109
|
version: '0'
|
110
|
+
- !ruby/object:Gem::Dependency
|
111
|
+
name: hashie
|
112
|
+
requirement: !ruby/object:Gem::Requirement
|
113
|
+
none: false
|
114
|
+
requirements:
|
115
|
+
- - ! '>='
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
118
|
+
type: :runtime
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
none: false
|
122
|
+
requirements:
|
123
|
+
- - ! '>='
|
124
|
+
- !ruby/object:Gem::Version
|
125
|
+
version: '0'
|
110
126
|
- !ruby/object:Gem::Dependency
|
111
127
|
name: bundler
|
112
128
|
requirement: !ruby/object:Gem::Requirement
|
@@ -200,6 +216,8 @@ files:
|
|
200
216
|
- lib/lev/handle_with.rb
|
201
217
|
- lib/lev/handler.rb
|
202
218
|
- lib/lev/handler_helper.rb
|
219
|
+
- lib/lev/object.rb
|
220
|
+
- lib/lev/outputs.rb
|
203
221
|
- lib/lev/routine.rb
|
204
222
|
- lib/lev/term_mapper.rb
|
205
223
|
- lib/lev/transaction_isolation.rb
|
@@ -207,6 +225,7 @@ files:
|
|
207
225
|
- lib/lev/version.rb
|
208
226
|
- spec/create_sprocket_spec.rb
|
209
227
|
- spec/deep_merge_spec.rb
|
228
|
+
- spec/outputs_spec.rb
|
210
229
|
- spec/routine_spec.rb
|
211
230
|
- spec/spec_helper.rb
|
212
231
|
- spec/sprocket_spec.rb
|
@@ -227,7 +246,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
227
246
|
version: '0'
|
228
247
|
segments:
|
229
248
|
- 0
|
230
|
-
hash:
|
249
|
+
hash: 55854544372342664
|
231
250
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
232
251
|
none: false
|
233
252
|
requirements:
|
@@ -236,7 +255,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
236
255
|
version: '0'
|
237
256
|
segments:
|
238
257
|
- 0
|
239
|
-
hash:
|
258
|
+
hash: 55854544372342664
|
240
259
|
requirements: []
|
241
260
|
rubyforge_project:
|
242
261
|
rubygems_version: 1.8.25
|
@@ -246,6 +265,7 @@ summary: Ride the rails but don't touch them.
|
|
246
265
|
test_files:
|
247
266
|
- spec/create_sprocket_spec.rb
|
248
267
|
- spec/deep_merge_spec.rb
|
268
|
+
- spec/outputs_spec.rb
|
249
269
|
- spec/routine_spec.rb
|
250
270
|
- spec/spec_helper.rb
|
251
271
|
- spec/sprocket_spec.rb
|