setl 0.0.3 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 9b1728e14e5c1c6a904512d241d340315ea4085a
4
- data.tar.gz: f33f22366920fbd08bf2a0451a1e5257f279239c
3
+ metadata.gz: 3a89bb7b59c0609b79d8cf15d6028ec1f737beae
4
+ data.tar.gz: cc162c0522666a70fbf9180592e4b0d3e5d128aa
5
5
  SHA512:
6
- metadata.gz: 0b4629edc8c4623270e7bdf7a65cec66dd04b4ef6e615421c3198228cf3d68e13d2553a6573675ac88d6476ba2fd3fa3e42be4c687407e5aa546305a11fe08e8
7
- data.tar.gz: d2622daeb250e0022d6a055588a0ef205ad9279c38a346f5a1b9b605c100ec4a7e06c9f06f9d7509f8474ed7fbc53c38b9738b2608e8ccbae50e091dccf717b0
6
+ metadata.gz: 15e2d85fef8add097abbda5890201332de3fc251f73e4e61b7c15cb74dcc5f09c64352e039db1411cab8506fe91142157079bebcc96233aed039270a73e70244
7
+ data.tar.gz: 4c57e706725c5f33b6b5d820bb444590c0508b0b78a2bf47cf8ad9b6d1d6715fdd763e06f42da3a5f040a042d2b4511e4ad6a20c4dab0fd38c49da246e037a1a
@@ -0,0 +1,43 @@
1
+ require_relative 'errors'
2
+
3
+ module Setl
4
+ class Delegator
5
+ def initialize(item, error_handler)
6
+ @item = item
7
+ @error_handler = error_handler
8
+ end
9
+
10
+ private
11
+
12
+ attr_reader :item, :error_handler
13
+ end
14
+
15
+ class Source < Delegator
16
+ def each(&block)
17
+ item.each(&block)
18
+ rescue StandardError => e
19
+ # Allow our errors to go through
20
+ if e.is_a? ETLError
21
+ raise e
22
+ else
23
+ error_handler.(SourceError.new("Failed to read from source"))
24
+ end
25
+ end
26
+ end
27
+
28
+ class Transform < Delegator
29
+ def call(row, &block)
30
+ item.call(row, &block)
31
+ rescue StandardError => e
32
+ error_handler.(ProcessingError.new(row, "Failed to process #{row}"))
33
+ end
34
+ end
35
+
36
+ class Destination < Delegator
37
+ def call(row, &block)
38
+ item.call(row, &block)
39
+ rescue StandardError => e
40
+ error_handler.(DestinationError.new(row, "Failed to send #{row}"))
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,25 @@
1
+ module Setl
2
+ class ETLError < StandardError
3
+ end
4
+
5
+ class ProcessingError < ETLError
6
+ def initialize(row, message=nil)
7
+ super message
8
+ @row = row
9
+ end
10
+
11
+ attr_reader :row
12
+ end
13
+
14
+ class SourceError < ETLError
15
+ end
16
+
17
+ class DestinationError < ETLError
18
+ def initialize(row, message=nil)
19
+ super message
20
+ @row = row
21
+ end
22
+
23
+ attr_reader :row
24
+ end
25
+ end
data/lib/setl/etl.rb CHANGED
@@ -1,21 +1,21 @@
1
+ require_relative 'delegates'
2
+
1
3
  module Setl
2
4
  class ETL
3
- def initialize(source, destination, stop_on_errors: false, error_handler: nil)
4
- @source = source
5
- @destination = destination
5
+ def initialize(source, destination, transform, stop_on_errors: false, error_handler: nil)
6
6
  @stop_on_errors = stop_on_errors
7
7
  @error_handler = error_handler || DefaultHandler.new(stop_on_errors)
8
+
9
+ @source = Source.new(source, @error_handler)
10
+ @destination = Destination.new(destination, @error_handler)
11
+ @transform = Transform.new(transform, @error_handler)
8
12
  end
9
13
 
10
- def process(transform)
14
+ def process
11
15
  source.each do |row|
12
16
  @last_row = row
13
17
 
14
- begin
15
- destination.(transform.(row))
16
- rescue StandardError => e
17
- error_handler.(row, e)
18
- end
18
+ destination.(transform.(row))
19
19
  end
20
20
  end
21
21
 
@@ -23,10 +23,7 @@ module Setl
23
23
 
24
24
  private
25
25
 
26
- attr_reader :source, :destination, :stop_on_errors, :error_handler
27
- end
28
-
29
- class ProcessingError < StandardError
26
+ attr_reader :source, :destination, :transform, :stop_on_errors, :error_handler
30
27
  end
31
28
 
32
29
  class DefaultHandler
@@ -34,8 +31,8 @@ module Setl
34
31
  @reraise = reraise
35
32
  end
36
33
 
37
- def call(row, exception)
38
- raise ProcessingError, "Failed to process #{row}" if reraise?
34
+ def call(exception)
35
+ raise exception if reraise?
39
36
  end
40
37
 
41
38
  private
data/lib/setl/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Setl
2
- VERSION = "0.0.3"
2
+ VERSION = "0.0.4"
3
3
  end
@@ -3,7 +3,7 @@ require 'setl/etl'
3
3
 
4
4
  module Setl
5
5
  RSpec.describe 'error handling' do
6
- let(:etl) { ETL.new(source, destination) }
6
+ let(:etl) { ETL.new(source, destination, transform) }
7
7
  let(:source) { [1, 2] }
8
8
  let(:destination) { double('Destination', call: true) }
9
9
  let(:transform) do
@@ -14,7 +14,7 @@ module Setl
14
14
  end
15
15
  end
16
16
 
17
- let(:process) { etl.process(transform) }
17
+ let(:process) { etl.process }
18
18
 
19
19
  context 'by default' do
20
20
  it 'rescues the error' do
@@ -29,7 +29,7 @@ module Setl
29
29
  end
30
30
 
31
31
  context 'when configured to stop on errors' do
32
- let(:etl) { ETL.new(source, destination, stop_on_errors: true) }
32
+ let(:etl) { ETL.new(source, destination, transform, stop_on_errors: true) }
33
33
 
34
34
  it 'stops processing when a processing error occurs' do
35
35
  expect { process }.to raise_error(ProcessingError, 'Failed to process 1')
@@ -45,14 +45,64 @@ module Setl
45
45
  end
46
46
 
47
47
  context 'when provided an error handler' do
48
- let(:handler) { double('Error Handler') }
49
- let(:etl) { ETL.new(source, destination, error_handler: handler) }
48
+ let(:handler) do
49
+ Class.new do
50
+ def self.call(exception)
51
+ raise exception
52
+ end
53
+ end
54
+ end
50
55
 
51
- it 'sends the row and exception to the handler' do
52
- expect(handler).to receive(:call).with(1, an_instance_of(RuntimeError))
56
+ let(:etl) { ETL.new(source, destination, transform, error_handler: handler) }
57
+
58
+ it 'sends a processing error to the handler' do
59
+ expect(handler).to receive(:call).with(an_instance_of(ProcessingError))
53
60
 
54
61
  process
55
62
  end
63
+
64
+ specify 'the error contains the original cause' do
65
+ begin
66
+ process
67
+ rescue ProcessingError => e
68
+ expect(e.cause).to be_a RuntimeError
69
+ end
70
+ end
71
+
72
+ context 'when the source raises an exception' do
73
+ let(:handler) { double('ErrorHandler', call: true) }
74
+
75
+ let(:source) do
76
+ Class.new do
77
+ def self.each
78
+ raise "nope"
79
+ end
80
+ end
81
+ end
82
+
83
+ it 'sends a SourceError to the handler' do
84
+ expect(handler).to receive(:call).with(an_instance_of(SourceError))
85
+
86
+ process
87
+ end
88
+ end
89
+
90
+ context 'when the destination raises an exception' do
91
+ let(:handler) { double('ErrorHandler', call: true) }
92
+ let(:destination) do
93
+ Class.new do
94
+ def self.call(row)
95
+ raise "lol"
96
+ end
97
+ end
98
+ end
99
+
100
+ it 'sends a destination error to the handler' do
101
+ expect(handler).to receive(:call).with(an_instance_of(DestinationError))
102
+
103
+ process
104
+ end
105
+ end
56
106
  end
57
107
  end
58
108
  end
data/spec/etl_spec.rb CHANGED
@@ -3,7 +3,7 @@ require 'setl/etl'
3
3
 
4
4
  module Setl
5
5
  RSpec.describe 'etl' do
6
- let(:etl) { ETL.new(source, destination) }
6
+ let(:etl) { ETL.new(source, destination, transform) }
7
7
 
8
8
  describe 'processing a row' do
9
9
  let(:row) { 'hello' }
@@ -13,7 +13,7 @@ module Setl
13
13
  let(:transform) { double('Transform', call: processed_data) }
14
14
 
15
15
  before do
16
- etl.process(transform)
16
+ etl.process
17
17
  end
18
18
 
19
19
  it 'delegates the processing to the transform' do
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: setl
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.0.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Leonard Garvey
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-09-21 00:00:00.000000000 Z
11
+ date: 2015-09-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -70,6 +70,8 @@ files:
70
70
  - bin/rspec
71
71
  - lib/setl.rb
72
72
  - lib/setl/controller.rb
73
+ - lib/setl/delegates.rb
74
+ - lib/setl/errors.rb
73
75
  - lib/setl/etl.rb
74
76
  - lib/setl/version.rb
75
77
  - setl.gemspec
@@ -97,7 +99,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
97
99
  version: '0'
98
100
  requirements: []
99
101
  rubyforge_project:
100
- rubygems_version: 2.4.5
102
+ rubygems_version: 2.2.2
101
103
  signing_key:
102
104
  specification_version: 4
103
105
  summary: Simple Extract Transform & Load - setl
@@ -106,3 +108,4 @@ test_files:
106
108
  - spec/error_handling_spec.rb
107
109
  - spec/etl_spec.rb
108
110
  - spec/spec_helper.rb
111
+ has_rdoc: