masamune 0.17.6 → 0.17.7

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: c29146a9633b2cf7760df9db790297c0889d856c
4
- data.tar.gz: d655ab1bd2088a9535b132dba044fe94a9c6eaa8
3
+ metadata.gz: 36f6999cb7287d4d466015d50c502be5330b1b9f
4
+ data.tar.gz: 39ff7b7dbd08db306bd2c35d7058f5e8040b781e
5
5
  SHA512:
6
- metadata.gz: bd15f96322e460a7e01c88465d4b245ee27242729c06b0567ad788fd5d02c57a72aea02b5e7cf58d9fe5217018e33b271f6723c8e522fcea37fbbb95b56afbbd
7
- data.tar.gz: 79c5a0895b9a64ff4a7b0ce388fc344a05e21b10c674b1069fe671ce486e55e2eaddb8e81792f513da95dec966f4e9380b537627faa93e75f19828ebf90df414
6
+ metadata.gz: 3c5d779aae19fd7b39f427e151c218c3d54fa1ede5596018a485ce8e0c25a66bee9307a0c314be2a0239a9adcfd036316240a4de9d40d04285743f673fca7669
7
+ data.tar.gz: 99acb8d19ce4458ac58636aaa2a5f31817000d6e11df4af086e1e59c73c0bb27bf5080cc937c2941961c713b4f3714ef32390fa6dad976d3ca946f143e2fd7ba
@@ -288,7 +288,7 @@ module Masamune::Schema
288
288
  {}
289
289
  end
290
290
  when :string
291
- value.to_s
291
+ value.blank? ? nil : value.to_s
292
292
  else
293
293
  value
294
294
  end
@@ -105,22 +105,20 @@ module Masamune::Schema
105
105
  raise 'must call Buffer#bind first' unless @io
106
106
  CSV.parse(JSONEncoder.new(@io, @store), options.merge(headers: @store.headers || @table.columns.keys)) do |data|
107
107
  next if data.to_s =~ /\A#/
108
- yield safe_row(data)
108
+ row = safe_row(data)
109
+ yield row.to_hash if row
109
110
  @line += 1
110
111
  end
111
112
  end
112
113
 
113
114
  def append(data)
114
115
  raise 'must call Buffer#bind first' unless @io
115
- row = Masamune::Schema::Row.new(parent: @table, values: data.to_hash)
116
+ row = safe_row(data)
117
+ return unless row
116
118
  write_headers = @store.headers && @line < 1
117
119
  @csv ||= CSV.new(@io, options.merge(headers: row.headers, write_headers: write_headers))
118
- if row.missing_required_columns.any?
119
- missing_required_column_names = row.missing_required_columns.map(&:name)
120
- @map.skip_or_raise(self, row, "missing required columns '#{missing_required_column_names.join(', ')}'")
121
- else
122
- @csv << row.serialize if append?(row.serialize)
123
- end
120
+ @csv << row.serialize if row.valid? && append?(row.serialize)
121
+ ensure
124
122
  @line += 1
125
123
  end
126
124
 
@@ -157,10 +155,10 @@ module Masamune::Schema
157
155
  end
158
156
 
159
157
  def safe_row(data)
160
- row = Masamune::Schema::Row.new(parent: @table, values: data.to_hash, strict: false)
161
- row.to_hash
162
- rescue
163
- @map.skip_or_raise(self, data, 'failed to parse')
158
+ Masamune::Schema::Row.new(parent: @table, values: data.to_hash, strict: @map.fail_fast)
159
+ rescue => e
160
+ @map.skip_or_raise(self, data, e.message || 'failed to parse')
161
+ nil
164
162
  end
165
163
 
166
164
  def append?(elem)
@@ -36,7 +36,10 @@ module Masamune::Schema
36
36
  attr_accessor attr
37
37
  end
38
38
 
39
+ attr_reader :errors
40
+
39
41
  def initialize(opts = {})
42
+ @errors = Set.new
40
43
  opts.symbolize_keys!
41
44
  DEFAULT_ATTRIBUTES.merge(opts).each do |name, value|
42
45
  public_send("#{name}=", value)
@@ -54,7 +57,8 @@ module Masamune::Schema
54
57
 
55
58
  def parent=(parent)
56
59
  @parent = parent
57
- normalize_values! if @parent
60
+ normalize! if @parent
61
+ validate! if @parent
58
62
  end
59
63
 
60
64
  def name(column = nil)
@@ -104,18 +108,22 @@ module Masamune::Schema
104
108
  column.sql_value(values[column.name])
105
109
  end
106
110
 
107
- def missing_required_columns
108
- Set.new.tap do |missing|
109
- values.select do |key, value|
110
- column = @columns[key]
111
- missing << column if column.required_value? && value.nil?
112
- end
113
- end
111
+ def valid?
112
+ errors.empty?
113
+ end
114
+
115
+ def invalid?
116
+ errors.any?
117
+ end
118
+
119
+ def validate!
120
+ validate_required_columns!
121
+ raise errors.first if invalid?
114
122
  end
115
123
 
116
124
  private
117
125
 
118
- def normalize_values!
126
+ def normalize!
119
127
  result = {}
120
128
  @columns = {}
121
129
  values.each do |key, value|
@@ -124,10 +132,23 @@ module Masamune::Schema
124
132
  @columns[column.compact_name] = column
125
133
  result[column.compact_name] = column.ruby_value(value)
126
134
  elsif strict
127
- raise ArgumentError, "#{@values} contains undefined columns #{key}"
135
+ @errors << "#{@values} contains undefined columns #{key}"
128
136
  end
129
137
  end
130
138
  @values = result
131
139
  end
140
+
141
+ def validate_required_columns!
142
+ @errors << "missing required columns '#{missing_required_columns.map(&:name).join(', ')}'" if missing_required_columns.any?
143
+ end
144
+
145
+ def missing_required_columns
146
+ Set.new.tap do |missing|
147
+ values.select do |key, value|
148
+ column = @columns[key]
149
+ missing << column if column.required_value? && value.nil?
150
+ end
151
+ end
152
+ end
132
153
  end
133
154
  end
@@ -21,5 +21,5 @@
21
21
  # THE SOFTWARE.
22
22
 
23
23
  module Masamune
24
- VERSION = '0.17.6'
24
+ VERSION = '0.17.7'
25
25
  end
@@ -364,6 +364,30 @@ describe Masamune::Schema::Column do
364
364
  end
365
365
  end
366
366
 
367
+ context 'with type :string' do
368
+ let(:column) { described_class.new(id: 'string', type: :string) }
369
+
370
+ context 'when nil' do
371
+ let(:value) { nil }
372
+ it { is_expected.to be(nil) }
373
+ end
374
+
375
+ context 'when blank' do
376
+ let(:value) { '' }
377
+ it { is_expected.to be(nil) }
378
+ end
379
+
380
+ context 'when String' do
381
+ let(:value) { 'value' }
382
+ it { is_expected.to eq('value') }
383
+ end
384
+
385
+ context 'when Integer' do
386
+ let(:value) { '1' }
387
+ it { is_expected.to eq('1') }
388
+ end
389
+ end
390
+
367
391
  context 'with type :timestamp' do
368
392
  let(:column) { described_class.new(id: 'timestamp', type: :timestamp) }
369
393
 
@@ -80,7 +80,7 @@ describe Masamune::Schema::Dimension do
80
80
  ]
81
81
  end
82
82
 
83
- it { expect { dimension }.to raise_error ArgumentError, /contains undefined columns/ }
83
+ it { expect { dimension }.to raise_error /contains undefined columns/ }
84
84
  end
85
85
 
86
86
  context 'for type :four' do
@@ -176,22 +176,20 @@ describe Masamune::Schema::Map do
176
176
  end
177
177
 
178
178
  before do
179
- expect(environment.logger).to receive(:warn).with(/missing required columns 'user_id'/).ordered
179
+ expect(environment.logger).to receive(:warn).with(/missing required columns 'id'/).ordered
180
180
  expect(environment.logger).to receive(:debug).with(
181
- :message => %q(missing required columns 'user_id'),
181
+ :message => %q(missing required columns 'id'),
182
182
  :source => 'user_stage',
183
183
  :target => 'user_dimension_ledger',
184
- :file => output.path,
184
+ :file => input.path,
185
185
  :line => 3,
186
186
  :row => {
187
- 'tenant_id' => 50,
188
- 'user_id' => nil,
189
- 'user_account_state.name' => 'active',
190
- 'hr_user_account_state.name' => 'active',
191
- 'admin' => false,
192
- 'preferences' => {},
193
- 'source' => 'users_file',
194
- 'cluster_id' => 100
187
+ 'id' => nil,
188
+ 'tenant_id' => '50',
189
+ 'junk_id' => 'X',
190
+ 'deleted_at' => nil,
191
+ 'admin' => '0',
192
+ 'preferences' => nil
195
193
  }
196
194
  ).ordered
197
195
  end
@@ -253,9 +251,9 @@ describe Masamune::Schema::Map do
253
251
  "deleted_at" => nil
254
252
  }
255
253
  ).ordered
256
- expect(environment.logger).to receive(:warn).with(/failed to parse/).ordered
254
+ expect(environment.logger).to receive(:warn).with("Could not coerce 'INVALID_JSON' into :json for column 'preferences'").ordered
257
255
  expect(environment.logger).to receive(:debug).with(
258
- :message => "failed to parse",
256
+ :message => "Could not coerce 'INVALID_JSON' into :json for column 'preferences'",
259
257
  :source => "input_stage",
260
258
  :target => "user_dimension_ledger",
261
259
  :file => input.path,
@@ -135,7 +135,7 @@ describe Masamune::Schema::Table do
135
135
  ]
136
136
  end
137
137
 
138
- it { expect { table }.to raise_error ArgumentError, /contains undefined columns/ }
138
+ it { expect { table }.to raise_error /contains undefined columns/ }
139
139
  end
140
140
 
141
141
  context 'with partial values' do
metadata CHANGED
@@ -1,195 +1,195 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: masamune
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.17.6
4
+ version: 0.17.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Michael Andrews
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-02-25 00:00:00.000000000 Z
11
+ date: 2016-03-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: thor
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - '>='
17
+ - - ">="
18
18
  - !ruby/object:Gem::Version
19
19
  version: '0'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - '>='
24
+ - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: activesupport
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - '>='
31
+ - - ">="
32
32
  - !ruby/object:Gem::Version
33
33
  version: '0'
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - '>='
38
+ - - ">="
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: tzinfo
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - '>='
45
+ - - ">="
46
46
  - !ruby/object:Gem::Version
47
47
  version: '0'
48
48
  type: :runtime
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - '>='
52
+ - - ">="
53
53
  - !ruby/object:Gem::Version
54
54
  version: '0'
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: chronic
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
- - - '>='
59
+ - - ">="
60
60
  - !ruby/object:Gem::Version
61
61
  version: '0'
62
62
  type: :runtime
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
- - - '>='
66
+ - - ">="
67
67
  - !ruby/object:Gem::Version
68
68
  version: '0'
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: tilt
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
- - - '>='
73
+ - - ">="
74
74
  - !ruby/object:Gem::Version
75
75
  version: '0'
76
76
  type: :runtime
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
- - - '>='
80
+ - - ">="
81
81
  - !ruby/object:Gem::Version
82
82
  version: '0'
83
83
  - !ruby/object:Gem::Dependency
84
84
  name: erubis
85
85
  requirement: !ruby/object:Gem::Requirement
86
86
  requirements:
87
- - - '>='
87
+ - - ">="
88
88
  - !ruby/object:Gem::Version
89
89
  version: '0'
90
90
  type: :runtime
91
91
  prerelease: false
92
92
  version_requirements: !ruby/object:Gem::Requirement
93
93
  requirements:
94
- - - '>='
94
+ - - ">="
95
95
  - !ruby/object:Gem::Version
96
96
  version: '0'
97
97
  - !ruby/object:Gem::Dependency
98
98
  name: parallel
99
99
  requirement: !ruby/object:Gem::Requirement
100
100
  requirements:
101
- - - '>='
101
+ - - ">="
102
102
  - !ruby/object:Gem::Version
103
103
  version: '0'
104
104
  type: :runtime
105
105
  prerelease: false
106
106
  version_requirements: !ruby/object:Gem::Requirement
107
107
  requirements:
108
- - - '>='
108
+ - - ">="
109
109
  - !ruby/object:Gem::Version
110
110
  version: '0'
111
111
  - !ruby/object:Gem::Dependency
112
112
  name: pry
113
113
  requirement: !ruby/object:Gem::Requirement
114
114
  requirements:
115
- - - '>='
115
+ - - ">="
116
116
  - !ruby/object:Gem::Version
117
117
  version: '0'
118
118
  type: :runtime
119
119
  prerelease: false
120
120
  version_requirements: !ruby/object:Gem::Requirement
121
121
  requirements:
122
- - - '>='
122
+ - - ">="
123
123
  - !ruby/object:Gem::Version
124
124
  version: '0'
125
125
  - !ruby/object:Gem::Dependency
126
126
  name: rb-readline
127
127
  requirement: !ruby/object:Gem::Requirement
128
128
  requirements:
129
- - - '>='
129
+ - - ">="
130
130
  - !ruby/object:Gem::Version
131
131
  version: '0'
132
132
  type: :runtime
133
133
  prerelease: false
134
134
  version_requirements: !ruby/object:Gem::Requirement
135
135
  requirements:
136
- - - '>='
136
+ - - ">="
137
137
  - !ruby/object:Gem::Version
138
138
  version: '0'
139
139
  - !ruby/object:Gem::Dependency
140
140
  name: rake
141
141
  requirement: !ruby/object:Gem::Requirement
142
142
  requirements:
143
- - - '>='
143
+ - - ">="
144
144
  - !ruby/object:Gem::Version
145
145
  version: '0.9'
146
146
  type: :development
147
147
  prerelease: false
148
148
  version_requirements: !ruby/object:Gem::Requirement
149
149
  requirements:
150
- - - '>='
150
+ - - ">="
151
151
  - !ruby/object:Gem::Version
152
152
  version: '0.9'
153
153
  - !ruby/object:Gem::Dependency
154
154
  name: user_agent_parser
155
155
  requirement: !ruby/object:Gem::Requirement
156
156
  requirements:
157
- - - '>='
157
+ - - ">="
158
158
  - !ruby/object:Gem::Version
159
159
  version: '0'
160
160
  type: :development
161
161
  prerelease: false
162
162
  version_requirements: !ruby/object:Gem::Requirement
163
163
  requirements:
164
- - - '>='
164
+ - - ">="
165
165
  - !ruby/object:Gem::Version
166
166
  version: '0'
167
167
  - !ruby/object:Gem::Dependency
168
168
  name: rspec
169
169
  requirement: !ruby/object:Gem::Requirement
170
170
  requirements:
171
- - - '>'
171
+ - - ">"
172
172
  - !ruby/object:Gem::Version
173
173
  version: '2.99'
174
174
  type: :development
175
175
  prerelease: false
176
176
  version_requirements: !ruby/object:Gem::Requirement
177
177
  requirements:
178
- - - '>'
178
+ - - ">"
179
179
  - !ruby/object:Gem::Version
180
180
  version: '2.99'
181
181
  - !ruby/object:Gem::Dependency
182
182
  name: byebug
183
183
  requirement: !ruby/object:Gem::Requirement
184
184
  requirements:
185
- - - '>='
185
+ - - ">="
186
186
  - !ruby/object:Gem::Version
187
187
  version: '0'
188
188
  type: :development
189
189
  prerelease: false
190
190
  version_requirements: !ruby/object:Gem::Requirement
191
191
  requirements:
192
- - - '>='
192
+ - - ">="
193
193
  - !ruby/object:Gem::Version
194
194
  version: '0'
195
195
  description: Hybrid Data & Work Flow
@@ -426,17 +426,17 @@ require_paths:
426
426
  - lib
427
427
  required_ruby_version: !ruby/object:Gem::Requirement
428
428
  requirements:
429
- - - '>='
429
+ - - ">="
430
430
  - !ruby/object:Gem::Version
431
431
  version: '0'
432
432
  required_rubygems_version: !ruby/object:Gem::Requirement
433
433
  requirements:
434
- - - '>='
434
+ - - ">="
435
435
  - !ruby/object:Gem::Version
436
436
  version: '0'
437
437
  requirements: []
438
438
  rubyforge_project:
439
- rubygems_version: 2.4.8
439
+ rubygems_version: 2.5.1
440
440
  signing_key:
441
441
  specification_version: 4
442
442
  summary: Hybrid Data & Work Flow