stockboy 0.8.0 → 0.8.1

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 90e9bfd03d069c571ffd1e6e03dd018cf477289c
4
- data.tar.gz: f0f88cdbbf0e65a8eadddf0e390d91f3c1a5f4c4
3
+ metadata.gz: e9478014be3b55b4e3c8c106a418e4f8fb9940bd
4
+ data.tar.gz: 46ca2d7e3bd6d567eca0f3ae26842a522c231d3b
5
5
  SHA512:
6
- metadata.gz: d0686581b72dd43ef079e93f8b3336669f50919e5f8adaa5019b198d4ce39b61771584ffcab122640cadbe1bdb372d4745bb4f444ee3d3d799833f2f73215b2f
7
- data.tar.gz: 1b11eae674ea31430894a4e4f050e91f2011841a94f72c6b580269f446eab4a5e4baacdda616c70e3b0a889b13fdd8fa51633fec9e936401bd01399f45857ab1
6
+ metadata.gz: 74ae4dc70a0676ef4677e7fc62f700e291a6681996b27e9dae7112a136ba5ccb835ac53c5cced0cfedf8d3b9bc21fa83052e70b1fd5dc0288bc57ae129648451
7
+ data.tar.gz: 4ae8f8e91b4368e3aa5cc1a486ffa4cff87e9eb9aa68f0c198d840d80fa0346c2ba2a012ae60f8d25ac94d080d50917b732725af67f8e22325a7c7dbea8ce0ae
data/CHANGELOG.md CHANGED
@@ -1,5 +1,10 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.8.1 / 2014-04-24
4
+
5
+ * [BUGFIX] Support `data_size` for non-string providers
6
+ * [BUGFIX] Checks for nil data and nil configuration options
7
+
3
8
  ## 0.8.0 / 2014-04-02
4
9
 
5
10
  * [ENHANCEMENT] Expose `data_time` and `data_size` in repeater
data/README.md CHANGED
@@ -5,10 +5,10 @@
5
5
  [![Build Status](https://travis-ci.org/avit/stockboy.png)][travis]
6
6
  [![Code Climate](https://codeclimate.com/github/avit/stockboy.png)][climate]
7
7
 
8
- Stockboy helps you receive and unpack data onto your shelves. You might
9
- consider using it to synchronize data exported from external sources, or
10
- migrating your own data from legacy systems. (TL;DR, Stockboy is a Ruby
11
- [DSL][dsl] for doing [ETL][etl].)
8
+ Stockboy helps you receive and unpack data onto your shelves. It provides a DSL
9
+ for configuring data processing pipelines. You might consider using it to
10
+ synchronize data exported from external sources, as part of an [ETL][etl]
11
+ workflow, or migrating your own data from legacy systems.
12
12
 
13
13
  Full documentation available at [rdoc.info/gems/stockboy][rdoc]
14
14
 
data/lib/stockboy/job.rb CHANGED
@@ -116,6 +116,14 @@ module Stockboy
116
116
  provider.errors.empty?
117
117
  end
118
118
 
119
+ def data(&block)
120
+ provider.data(&block)
121
+ end
122
+
123
+ def data?(reduction=:all?)
124
+ provider.data?(reduction)
125
+ end
126
+
119
127
  # Count of all processed records
120
128
  #
121
129
  # @!attribute [r] total_records
@@ -209,6 +217,7 @@ module Stockboy
209
217
  def load_records
210
218
  reset
211
219
  load_all_records
220
+ return unless provider.data?
212
221
  partition_all_records
213
222
  @processed = true
214
223
  end
@@ -234,14 +243,20 @@ module Stockboy
234
243
  end
235
244
  end
236
245
 
246
+ # Allows for a data method that either yields or returns giving preference
247
+ # to the yield. It will ignore the data return value if it has yielded.
248
+ #
237
249
  def with_provider_data
238
250
  return to_enum(__method__) unless block_given?
239
251
  yielded = nil
240
252
  provider.data do |data|
241
- yielded = true
242
- yield data
253
+ if data
254
+ yielded = true
255
+ yield data
256
+ end
243
257
  end
244
- yield provider.data unless yielded
258
+ return if yielded
259
+ yield(provider.data) if provider.data
245
260
  end
246
261
 
247
262
  def record_partition(record)
@@ -81,8 +81,11 @@ module Stockboy
81
81
  @data
82
82
  end
83
83
 
84
- def data?
85
- @data_size && @data_size > 0
84
+ # Determine if there is returned data
85
+ #
86
+ def data?(_=nil)
87
+ return nil unless @data
88
+ @data && !@data.empty?
86
89
  end
87
90
 
88
91
  # Reset received data
@@ -5,22 +5,57 @@ module Stockboy
5
5
 
6
6
  YIELD_ONCE = proc { |output, provider| output << provider }
7
7
 
8
+ ProviderStats = Struct.new(:data_time, :data_size, :data_) do
9
+ def self.from(provider)
10
+ new(provider.data_time, provider.data_size, provider.data?)
11
+ end
12
+
13
+ alias :data? :data_ # 1.9 compatibility
14
+ end
15
+
8
16
  attr_reader :base_provider
9
- attr_reader :data_size
10
- attr_reader :data_time
11
17
 
12
18
  def initialize(provider, &yielder)
13
19
  @orig_provider = provider
14
20
  @base_provider = provider.dup
21
+ @iterations = []
15
22
  @yielder = yielder || YIELD_ONCE
16
23
  end
17
24
 
18
- def data?
19
- @data_size && @data_size > 0
25
+ # Determine if there was any returned data after processing iterations
26
+ # @param [:all?,:any?,:one?] reduction
27
+ # Specify if all iterations must return data to be valid, or just any
28
+ #
29
+ def data?(reduction = :all?)
30
+ return nil if data_iterations == 0
31
+ @iterations.send(reduction, &:data?)
32
+ end
33
+
34
+ # Get the total data size returned after processing iterations
35
+ #
36
+ def data_size
37
+ @iterations.reduce(nil) { |sum, source|
38
+ source.data_size ? source.data_size + sum.to_i : sum
39
+ }
40
+ end
41
+
42
+ # Get the last data time returned after processing iterations
43
+ #
44
+ def data_time
45
+ @iterations.reduce(nil) { |max, source|
46
+ source.data_time && (max.nil? || source.data_time > max) ? source.data_time : max
47
+ }
48
+ end
49
+
50
+ def data_iterations
51
+ @iterations.size
20
52
  end
21
53
 
22
54
  def data
23
- raise ArgumentError, "expects a block for yielding each data set" unless block_given?
55
+ unless block_given?
56
+ raise ArgumentError, "expect a block for yielding data iterations"
57
+ end
58
+
24
59
  each do |nth_provider|
25
60
  yield fetch_iteration_data(nth_provider)
26
61
  end
@@ -28,7 +63,7 @@ module Stockboy
28
63
 
29
64
  def clear
30
65
  @base_provider = @orig_provider.dup
31
- @data_time, @data_size = nil, nil
66
+ @iterations.clear
32
67
  super
33
68
  end
34
69
 
@@ -67,8 +102,7 @@ module Stockboy
67
102
 
68
103
  def fetch_iteration_data(provider)
69
104
  if provider.data
70
- @data_size = [@data_size, provider.data_size].compact.reduce(&:+)
71
- @data_time = [@data_time, provider.data_time].compact.max
105
+ @iterations << ProviderStats.from(provider)
72
106
  end
73
107
  provider.data
74
108
  end
@@ -116,6 +116,7 @@ module Stockboy::Providers
116
116
  rescue Net::FTPError => e
117
117
  errors << e.message
118
118
  logger.warn e.message
119
+ nil
119
120
  end
120
121
 
121
122
  def matching_file
@@ -61,7 +61,7 @@ module Stockboy::Providers
61
61
  dsl_attr :password
62
62
 
63
63
  def uri
64
- return nil if @uri.nil? || @uri.empty?
64
+ return nil if @uri.nil? || @uri.to_s.empty?
65
65
  URI(@uri).tap { |u| u.query = URI.encode_www_form(@query) if @query }
66
66
  end
67
67
 
@@ -126,18 +126,18 @@ module Stockboy::Providers
126
126
 
127
127
  def client
128
128
  orig_logger, HTTPI.logger = HTTPI.logger, logger
129
- req = HTTPI::Request.new(uri)
129
+ req = HTTPI::Request.new.tap { |c| c.url = uri }
130
130
  req.auth.basic(username, password) if username && password
131
- yield req if block_given?
131
+ block_given? ? yield(req) : req
132
+ ensure
132
133
  HTTPI.logger = orig_logger
133
- req
134
134
  end
135
135
 
136
136
  private
137
137
 
138
138
  def validate
139
- errors << "uri must be specified" if uri.blank?
140
- errors << "method (:get, :post) must be specified" if method.blank?
139
+ errors << "uri must be specified" unless uri
140
+ errors << "method (:get, :post) must be specified" unless method
141
141
  errors.empty?
142
142
  end
143
143
 
@@ -1,3 +1,3 @@
1
1
  module Stockboy
2
- VERSION = "0.8.0"
2
+ VERSION = "0.8.1"
3
3
  end
@@ -12,6 +12,7 @@ class TestProvider
12
12
  end
13
13
  def data_size; @data && @data.size end
14
14
  def data_time; @data && Time.now end
15
+ def data?; true end
15
16
  end
16
17
 
17
18
  class TestReader
@@ -79,7 +79,7 @@ module Stockboy
79
79
  its(:data_size) { should be_nil }
80
80
 
81
81
  context "after fetching" do
82
- before { provider.data }
82
+ before { provider.fetch_data }
83
83
  its(:data_size) { should be > 0 }
84
84
  end
85
85
  end
@@ -88,8 +88,8 @@ module Stockboy
88
88
  subject(:provider) { ProviderSubclass.new }
89
89
  its(:data_time) { should be_nil }
90
90
 
91
- context "after iterating" do
92
- before { provider.data }
91
+ context "after fetching" do
92
+ before { provider.fetch_data }
93
93
  its(:data_time) { should be_a Time }
94
94
  end
95
95
  end
@@ -98,8 +98,8 @@ module Stockboy
98
98
  subject(:provider) { ProviderSubclass.new }
99
99
  its(:data?) { should be_nil }
100
100
 
101
- context "after iterating" do
102
- before { provider.data }
101
+ context "after fetching" do
102
+ before { provider.fetch_data }
103
103
  its(:data?) { should be true }
104
104
  end
105
105
  end
@@ -72,6 +72,20 @@ module Stockboy
72
72
  end
73
73
  end
74
74
 
75
+ describe "#client" do
76
+ subject(:client) { provider.client }
77
+
78
+ before { provider.uri = "http://example.com/" }
79
+
80
+ it "should configure the base url" do
81
+ client.url.host.should == "example.com"
82
+ end
83
+
84
+ it "returns the value of the passed block" do
85
+ provider.client { |http| "DATA" }.should == "DATA"
86
+ end
87
+ end
88
+
75
89
  describe "#data" do
76
90
  let(:response) { HTTPI::Response.new(200, {}, '{"success":true}') }
77
91
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: stockboy
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.0
4
+ version: 0.8.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrew Vit
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-04-03 00:00:00.000000000 Z
11
+ date: 2014-04-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake