masamune 0.18.11 → 0.19.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Rakefile +1 -1
- data/lib/masamune/cached_filesystem.rb +1 -1
- data/lib/masamune/configuration.rb +1 -1
- data/lib/masamune/data_plan/rule.rb +1 -1
- data/lib/masamune/filesystem.rb +36 -36
- data/lib/masamune/schema/column.rb +7 -5
- data/lib/masamune/schema/dimension.rb +6 -6
- data/lib/masamune/schema/fact.rb +2 -2
- data/lib/masamune/schema/store.rb +1 -1
- data/lib/masamune/tasks/dump_thor.rb +2 -2
- data/lib/masamune/thor.rb +1 -1
- data/lib/masamune/transform/postgres/define_table.psql.erb +1 -1
- data/lib/masamune/version.rb +1 -1
- data/spec/masamune/actions/execute_spec.rb +2 -2
- data/spec/masamune/actions/transform_spec.rb +1 -1
- data/spec/masamune/commands/aws_emr_spec.rb +1 -1
- data/spec/masamune/commands/shell_spec.rb +4 -4
- data/spec/masamune/data_plan/builder_spec.rb +6 -6
- data/spec/masamune/filesystem_spec.rb +2 -2
- data/spec/masamune/schema/catalog_spec.rb +3 -3
- data/spec/masamune/schema/column_spec.rb +9 -9
- data/spec/masamune/schema/table_spec.rb +14 -14
- data/spec/masamune/thor_spec.rb +4 -4
- data/spec/masamune/transform/define_table.dimension_spec.rb +4 -4
- data/spec/masamune/transform/define_table.fact_spec.rb +3 -3
- data/spec/masamune/transform/define_table.table_spec.rb +6 -6
- data/spec/masamune/transform/denormalize_table_spec.rb +6 -6
- data/spec/masamune/transform/rollup_fact_spec.rb +1 -1
- data/spec/masamune/transform/stage_fact_spec.rb +2 -2
- data/spec/support/masamune/mock_filesystem.rb +1 -1
- data/spec/support/masamune/shared_example_group.rb +1 -1
- data/spec/support/masamune/task_example_group.rb +6 -6
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3449c74f195c657f9c934ca252ee55979fcf373c
|
4
|
+
data.tar.gz: e16324d9a0e4582bb4060acf6fcd920409909309
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 84f7dc5b7d970c6e46a17ddc6612244b193b88cebb01ebe40125197388a933fa3810b9f4bd0e5147b54e46a98e72f195f5b46f1cfbb3328725ea238fce52c96a
|
7
|
+
data.tar.gz: f9113e58e109151ac16372b94495837f97c6881a7a3a893bff990e767d3d4f40b65f3dbc3fa337b085d8efa7c8ba2510ed286a6752ac3128c589c1024672edf7
|
data/Rakefile
CHANGED
@@ -83,7 +83,7 @@ module Masamune
|
|
83
83
|
end
|
84
84
|
|
85
85
|
# FIXME: cache eviction policy can be more precise
|
86
|
-
[
|
86
|
+
%i[touch! mkdir! copy_file_to_file copy_file_to_dir copy_dir remove_file remove_dir move_file_to_file move_file_to_dir move_dir write].each do |method|
|
87
87
|
define_method(method) do |*args|
|
88
88
|
clear!
|
89
89
|
@filesystem.send(method, *args)
|
@@ -44,7 +44,7 @@ class Masamune::Configuration < Hashie::Dash
|
|
44
44
|
end
|
45
45
|
|
46
46
|
def default_commands
|
47
|
-
@default_commands ||= %i
|
47
|
+
@default_commands ||= %i[aws_emr hive hadoop_streaming hadoop_filesystem s3cmd postgres postgres_admin]
|
48
48
|
end
|
49
49
|
end
|
50
50
|
|
data/lib/masamune/filesystem.rb
CHANGED
@@ -283,26 +283,26 @@ module Masamune
|
|
283
283
|
def copy_dir(src, dst)
|
284
284
|
check_immutable_path!(dst)
|
285
285
|
case [type(src), type(dst)]
|
286
|
-
when [
|
286
|
+
when %i[hdfs hdfs]
|
287
287
|
copy_file_to_dir(src, dst)
|
288
|
-
when [
|
288
|
+
when %i[hdfs local]
|
289
289
|
copy_file_to_dir(src, dst)
|
290
|
-
when [
|
290
|
+
when %i[hdfs s3]
|
291
291
|
copy_file_to_dir(src, dst)
|
292
|
-
when [
|
292
|
+
when %i[s3 s3]
|
293
293
|
s3cmd('cp', '--recursive', s3b(src, dir: true), s3b(dst, dir: true))
|
294
|
-
when [
|
294
|
+
when %i[s3 local]
|
295
295
|
fixed_dst = File.join(dst, src.split('/')[-1])
|
296
296
|
FileUtils.mkdir_p(fixed_dst, file_util_args)
|
297
297
|
s3cmd('get', '--recursive', '--skip-existing', s3b(src, dir: true), fixed_dst)
|
298
|
-
when [
|
298
|
+
when %i[s3 hdfs]
|
299
299
|
copy_file_to_dir(src, dst)
|
300
|
-
when [
|
300
|
+
when %i[local local]
|
301
301
|
FileUtils.mkdir_p(dst, file_util_args)
|
302
302
|
FileUtils.cp_r(src, dst, file_util_args)
|
303
|
-
when [
|
303
|
+
when %i[local hdfs]
|
304
304
|
copy_file_to_dir(src, dst)
|
305
|
-
when [
|
305
|
+
when %i[local s3]
|
306
306
|
s3cmd('put', '--recursive', src, s3b(dst, dir: true))
|
307
307
|
end
|
308
308
|
end
|
@@ -348,27 +348,27 @@ module Masamune
|
|
348
348
|
def move_dir(src, dst)
|
349
349
|
check_immutable_path!(src)
|
350
350
|
case [type(src), type(dst)]
|
351
|
-
when [
|
351
|
+
when %i[hdfs hdfs]
|
352
352
|
move_file_to_file(src, dst)
|
353
|
-
when [
|
353
|
+
when %i[hdfs local]
|
354
354
|
copy_file_to_dir(src, dst)
|
355
355
|
remove_dir(src)
|
356
|
-
when [
|
356
|
+
when %i[s3 s3]
|
357
357
|
s3cmd('mv', '--recursive', d(src), f(dst))
|
358
|
-
when [
|
358
|
+
when %i[s3 local]
|
359
359
|
s3cmd('get', '--recursive', d(src), f(dst))
|
360
360
|
remove_dir(src)
|
361
|
-
when [
|
361
|
+
when %i[s3 hdfs]
|
362
362
|
copy_file_to_dir(src, dst)
|
363
363
|
remove_dir(src)
|
364
|
-
when [
|
364
|
+
when %i[hdfs s3]
|
365
365
|
copy_file_to_dir(src, d(dst))
|
366
366
|
remove_dir(src)
|
367
|
-
when [
|
367
|
+
when %i[local local]
|
368
368
|
move_file_to_file(src, dst)
|
369
|
-
when [
|
369
|
+
when %i[local hdfs]
|
370
370
|
move_file_to_file(src, dst)
|
371
|
-
when [
|
371
|
+
when %i[local s3]
|
372
372
|
s3cmd('put', '--recursive', d(src), d(dst))
|
373
373
|
remove_dir(src)
|
374
374
|
end
|
@@ -531,51 +531,51 @@ module Masamune
|
|
531
531
|
|
532
532
|
def copy_file_helper(src, dst, dir)
|
533
533
|
case [type(src), type(dst)]
|
534
|
-
when [
|
534
|
+
when %i[hdfs hdfs]
|
535
535
|
hadoop_fs('-cp', src, dst)
|
536
|
-
when [
|
536
|
+
when %i[hdfs local]
|
537
537
|
hadoop_fs('-copyToLocal', src, local_file_prefix(dst))
|
538
|
-
when [
|
538
|
+
when %i[hdfs s3]
|
539
539
|
hadoop_fs('-cp', src, s3n(dst))
|
540
|
-
when [
|
540
|
+
when %i[s3 s3]
|
541
541
|
s3cmd('cp', src, s3b(dst, dir: dir))
|
542
|
-
when [
|
542
|
+
when %i[s3 local]
|
543
543
|
s3cmd('get', src, dst)
|
544
|
-
when [
|
544
|
+
when %i[s3 hdfs]
|
545
545
|
hadoop_fs('-cp', s3n(src), dst)
|
546
|
-
when [
|
546
|
+
when %i[local local]
|
547
547
|
FileUtils.cp(src, dst, file_util_args)
|
548
|
-
when [
|
548
|
+
when %i[local hdfs]
|
549
549
|
hadoop_fs('-copyFromLocal', local_file_prefix(src), dst)
|
550
|
-
when [
|
550
|
+
when %i[local s3]
|
551
551
|
s3cmd('put', src, s3b(dst, dir: dir))
|
552
552
|
end
|
553
553
|
end
|
554
554
|
|
555
555
|
def move_file_helper(src, dst, dir)
|
556
556
|
case [type(src), type(dst)]
|
557
|
-
when [
|
557
|
+
when %i[hdfs hdfs]
|
558
558
|
hadoop_fs('-mv', src, dst)
|
559
|
-
when [
|
559
|
+
when %i[hdfs local]
|
560
560
|
# NOTE: moveToLocal: Option '-moveToLocal' is not implemented yet
|
561
561
|
hadoop_fs('-copyToLocal', src, local_file_prefix(dst))
|
562
562
|
hadoop_fs('-rm', src)
|
563
|
-
when [
|
563
|
+
when %i[hdfs s3]
|
564
564
|
copy_file_to_file(src, s3n(dst, dir: dir))
|
565
565
|
hadoop_fs('-rm', src)
|
566
|
-
when [
|
566
|
+
when %i[s3 s3]
|
567
567
|
s3cmd('mv', src, s3b(dst, dir: dir))
|
568
|
-
when [
|
568
|
+
when %i[s3 local]
|
569
569
|
s3cmd('get', src, dst)
|
570
570
|
s3cmd('del', src)
|
571
|
-
when [
|
571
|
+
when %i[s3 hdfs]
|
572
572
|
hadoop_fs('-mv', s3n(src), dst)
|
573
|
-
when [
|
573
|
+
when %i[local local]
|
574
574
|
FileUtils.mv(src, dst, file_util_args)
|
575
575
|
FileUtils.chmod(FILE_MODE, dst, file_util_args)
|
576
|
-
when [
|
576
|
+
when %i[local hdfs]
|
577
577
|
hadoop_fs('-moveFromLocal', local_file_prefix(src), dst)
|
578
|
-
when [
|
578
|
+
when %i[local s3]
|
579
579
|
s3cmd('put', src, s3b(dst, dir: dir))
|
580
580
|
FileUtils.rm(src, file_util_args)
|
581
581
|
end
|
@@ -287,7 +287,9 @@ module Masamune::Schema
|
|
287
287
|
when Hash
|
288
288
|
value
|
289
289
|
when String
|
290
|
-
JSON.parse(value)
|
290
|
+
JSON.parse(value).tap do |new_value|
|
291
|
+
raise unless new_value.is_a?(Hash) || new_value.is_a?(Array)
|
292
|
+
end
|
291
293
|
when nil
|
292
294
|
{}
|
293
295
|
end
|
@@ -354,7 +356,7 @@ module Masamune::Schema
|
|
354
356
|
end
|
355
357
|
|
356
358
|
def hash_value?
|
357
|
-
[
|
359
|
+
%i[key_value yaml json].include?(type)
|
358
360
|
end
|
359
361
|
|
360
362
|
def as_psql
|
@@ -404,11 +406,11 @@ module Masamune::Schema
|
|
404
406
|
def typecast?(other_type)
|
405
407
|
return true if type == other_type
|
406
408
|
case [type, other_type]
|
407
|
-
when [
|
409
|
+
when %i[key_value yaml]
|
408
410
|
true
|
409
|
-
when [
|
411
|
+
when %i[key_value json]
|
410
412
|
true
|
411
|
-
when [
|
413
|
+
when %i[yaml json]
|
412
414
|
true
|
413
415
|
else
|
414
416
|
false
|
@@ -22,7 +22,7 @@
|
|
22
22
|
|
23
23
|
module Masamune::Schema
|
24
24
|
class Dimension < Table
|
25
|
-
SUPPORTED_GRAINS = [
|
25
|
+
SUPPORTED_GRAINS = %i[hourly daily monthly].freeze
|
26
26
|
|
27
27
|
def initialize(opts = {})
|
28
28
|
opts.symbolize_keys!
|
@@ -81,11 +81,11 @@ module Masamune::Schema
|
|
81
81
|
when :one, :date
|
82
82
|
[:last_modified_at]
|
83
83
|
when :two
|
84
|
-
[
|
84
|
+
%i[start_at end_at version last_modified_at]
|
85
85
|
when :four
|
86
|
-
[
|
86
|
+
%i[start_at end_at version last_modified_at]
|
87
87
|
when :ledger
|
88
|
-
[
|
88
|
+
%i[source_kind source_uuid start_at last_modified_at delta]
|
89
89
|
else
|
90
90
|
super
|
91
91
|
end
|
@@ -117,14 +117,14 @@ module Masamune::Schema
|
|
117
117
|
when :one, :date
|
118
118
|
initialize_column! id: 'last_modified_at', type: :timestamp, default: 'NOW()'
|
119
119
|
when :two
|
120
|
-
initialize_column! id: 'start_at', type: :timestamp, default: 'TO_TIMESTAMP(0)', index: [
|
120
|
+
initialize_column! id: 'start_at', type: :timestamp, default: 'TO_TIMESTAMP(0)', index: %i[start_at natural], unique: :natural
|
121
121
|
initialize_column! id: 'end_at', type: :timestamp, null: true, index: :end_at
|
122
122
|
initialize_column! id: 'version', type: :integer, default: 1, null: true
|
123
123
|
initialize_column! id: 'last_modified_at', type: :timestamp, default: 'NOW()'
|
124
124
|
when :four
|
125
125
|
children << ledger_table
|
126
126
|
# FIXME: derive type from from parent
|
127
|
-
initialize_column! id: 'start_at', type: :timestamp, default: 'TO_TIMESTAMP(0)', index: [
|
127
|
+
initialize_column! id: 'start_at', type: :timestamp, default: 'TO_TIMESTAMP(0)', index: %i[start_at natural], unique: :natural
|
128
128
|
initialize_column! id: 'end_at', type: :timestamp, null: true, index: :end_at
|
129
129
|
initialize_column! id: 'version', type: :integer, default: 1, null: true
|
130
130
|
initialize_column! id: 'last_modified_at', type: :timestamp, default: 'NOW()'
|
data/lib/masamune/schema/fact.rb
CHANGED
@@ -22,7 +22,7 @@
|
|
22
22
|
|
23
23
|
module Masamune::Schema
|
24
24
|
class Fact < Table
|
25
|
-
SUPPORTED_GRAINS = [
|
25
|
+
SUPPORTED_GRAINS = %i[transaction hourly daily monthly].freeze
|
26
26
|
|
27
27
|
attr_accessor :grain
|
28
28
|
attr_accessor :partition
|
@@ -114,7 +114,7 @@ module Masamune::Schema
|
|
114
114
|
def reserved_column_ids
|
115
115
|
case type
|
116
116
|
when :fact
|
117
|
-
[
|
117
|
+
%i[time_key last_modified_at]
|
118
118
|
else
|
119
119
|
super
|
120
120
|
end
|
@@ -35,8 +35,8 @@ module Masamune::Tasks
|
|
35
35
|
skip_lock!
|
36
36
|
|
37
37
|
desc 'dump', 'Dump schema'
|
38
|
-
method_option :type, enum: %w
|
39
|
-
method_option :section, enum: %w
|
38
|
+
method_option :type, enum: %w[psql hql], desc: 'Schema type', default: 'psql'
|
39
|
+
method_option :section, enum: %w[pre post all], desc: 'Schema section', default: 'all'
|
40
40
|
method_option :exclude, type: :array, desc: 'Exclude tables matching globs', default: []
|
41
41
|
method_option :skip_indexes, type: :boolean, desc: 'Disable indexes', default: false
|
42
42
|
def dump_exec
|
data/lib/masamune/thor.rb
CHANGED
@@ -70,7 +70,7 @@ module Masamune
|
|
70
70
|
def start(*a)
|
71
71
|
super
|
72
72
|
rescue SignalException => e
|
73
|
-
raise e unless %w
|
73
|
+
raise e unless %w[SIGHUP SIGTERM].include?(e.to_s)
|
74
74
|
instance.logger.debug("Exiting at user request on #{e}")
|
75
75
|
exit 0
|
76
76
|
rescue ::Thor::MalformattedArgumentError, ::Thor::RequiredArgumentMissingError => e
|
@@ -84,7 +84,7 @@ END IF; END $$;
|
|
84
84
|
copy_options << "DELIMITER '\t'" if target.store.format == :tsv
|
85
85
|
copy_options << "HEADER true" if target.store.headers
|
86
86
|
-%>
|
87
|
-
COPY <%= target.name %> FROM '<%= file %>' WITH (<%= copy_options.join(", ") %>);
|
87
|
+
\COPY <%= target.name %> FROM '<%= file %>' WITH (<%= copy_options.join(", ") %>);
|
88
88
|
<%- end -%>
|
89
89
|
<%- end -%>
|
90
90
|
|
data/lib/masamune/version.rb
CHANGED
@@ -44,14 +44,14 @@ describe Masamune::Actions::Execute do
|
|
44
44
|
end
|
45
45
|
|
46
46
|
context 'with a simple command' do
|
47
|
-
let(:command) { %w
|
47
|
+
let(:command) { %w[echo ping] }
|
48
48
|
let(:options) { { fail_fast: true } }
|
49
49
|
|
50
50
|
it { expect { |b| instance.execute(*command, options, &b) }.to yield_with_args('ping', 0) }
|
51
51
|
end
|
52
52
|
|
53
53
|
context 'with a simple command with input' do
|
54
|
-
let(:command) { %w
|
54
|
+
let(:command) { %w[cat] }
|
55
55
|
let(:options) { { input: 'pong', fail_fast: true } }
|
56
56
|
|
57
57
|
it { expect { |b| instance.execute(*command, options, &b) }.to yield_with_args('pong', 0) }
|
@@ -44,7 +44,7 @@ describe Masamune::Actions::Transform do
|
|
44
44
|
column 'updated_at', type: :timestamp
|
45
45
|
end
|
46
46
|
|
47
|
-
fact 'visits', partition: 'y%Ym%m', grain: %w
|
47
|
+
fact 'visits', partition: 'y%Ym%m', grain: %w[hourly daily monthly] do
|
48
48
|
references :date
|
49
49
|
references :user
|
50
50
|
|
@@ -45,7 +45,7 @@ describe Masamune::Commands::AwsEmr do
|
|
45
45
|
describe '#command_args' do
|
46
46
|
subject { instance.command_args }
|
47
47
|
|
48
|
-
it { is_expected.to eq(%w
|
48
|
+
it { is_expected.to eq(%w[aws emr ssh]) }
|
49
49
|
|
50
50
|
context 'with --cluster-id j-XYZ' do
|
51
51
|
let(:delegate) { double(command_args: ['hive', '-e', "'show tables;'"]) }
|
@@ -116,7 +116,7 @@ describe Masamune::Commands::Shell do
|
|
116
116
|
end
|
117
117
|
|
118
118
|
it { expect(delegate.status).to eq(0) }
|
119
|
-
it { expect(delegate.stdout).to eq(%w
|
119
|
+
it { expect(delegate.stdout).to eq(%w[ping pong]) }
|
120
120
|
it { expect(delegate.stderr).to eq([]) }
|
121
121
|
end
|
122
122
|
|
@@ -172,17 +172,17 @@ describe Masamune::Commands::Shell do
|
|
172
172
|
|
173
173
|
context 'with command_args containing nil' do
|
174
174
|
let(:command_args) { ['echo', nil, 'foo'] }
|
175
|
-
it { is_expected.to eq(%w
|
175
|
+
it { is_expected.to eq(%w[echo foo]) }
|
176
176
|
end
|
177
177
|
|
178
178
|
context 'with command_args containing an integer' do
|
179
179
|
let(:command_args) { ['echo', nil, 5] }
|
180
|
-
it { is_expected.to eq(%w
|
180
|
+
it { is_expected.to eq(%w[echo 5]) }
|
181
181
|
end
|
182
182
|
|
183
183
|
context 'with nested command_args' do
|
184
184
|
let(:command_args) { [['echo'], ['foo']] }
|
185
|
-
it { is_expected.to eq(%w
|
185
|
+
it { is_expected.to eq(%w[echo foo]) }
|
186
186
|
end
|
187
187
|
end
|
188
188
|
end
|
@@ -27,8 +27,8 @@ describe Masamune::DataPlan::Builder do
|
|
27
27
|
end
|
28
28
|
|
29
29
|
context 'with multiple namespaces' do
|
30
|
-
let(:namespaces) { %w
|
31
|
-
let(:commands) { %w
|
30
|
+
let(:namespaces) { %w[a b] }
|
31
|
+
let(:commands) { %w[load store] }
|
32
32
|
let(:sources) { [{ path: 'log/%Y%m%d.*.log' }, { path: 'table/y=%Y/m=%m/d=%d' }] }
|
33
33
|
let(:targets) { [{ path: 'table/y=%Y/m=%m/d=%d' }, { path: 'daily/%Y-%m-%d' }] }
|
34
34
|
|
@@ -47,8 +47,8 @@ describe Masamune::DataPlan::Builder do
|
|
47
47
|
end
|
48
48
|
|
49
49
|
context 'with :for option' do
|
50
|
-
let(:namespaces) { %w
|
51
|
-
let(:commands) { %w
|
50
|
+
let(:namespaces) { %w[a a a] }
|
51
|
+
let(:commands) { %w[missing_before override missing_after] }
|
52
52
|
let(:sources) { [{ path: 'log/%Y%m%d.*.log', for: 'override' }] }
|
53
53
|
let(:targets) { [{ path: 'table/y=%Y/m=%m/d=%d', for: 'override' }] }
|
54
54
|
|
@@ -70,8 +70,8 @@ describe Masamune::DataPlan::Builder do
|
|
70
70
|
end
|
71
71
|
|
72
72
|
context 'with :skip option' do
|
73
|
-
let(:namespaces) { %w
|
74
|
-
let(:commands) { %w
|
73
|
+
let(:namespaces) { %w[a a a] }
|
74
|
+
let(:commands) { %w[missing_before override] }
|
75
75
|
let(:sources) { [{ skip: true }, { path: 'log/%Y%m%d.*.log' }] }
|
76
76
|
let(:targets) { [{ skip: true }, { path: 'table/y=%Y/m=%m/d=%d' }] }
|
77
77
|
|
@@ -739,14 +739,14 @@ shared_examples_for 'Filesystem' do
|
|
739
739
|
|
740
740
|
describe '#glob_sort' do
|
741
741
|
before do
|
742
|
-
allow_any_instance_of(Masamune::Filesystem).to receive(:glob).and_return(%w
|
742
|
+
allow_any_instance_of(Masamune::Filesystem).to receive(:glob).and_return(%w[/tmp/a/02.txt /tmp/b/01.txt /tmp/c/00.txt])
|
743
743
|
end
|
744
744
|
|
745
745
|
subject do
|
746
746
|
instance.glob_sort('/tmp/*', order: :basename)
|
747
747
|
end
|
748
748
|
|
749
|
-
it { is_expected.to eq(%w
|
749
|
+
it { is_expected.to eq(%w[/tmp/c/00.txt /tmp/b/01.txt /tmp/a/02.txt]) }
|
750
750
|
it { expect { |b| instance.glob_sort('/tmp/*', order: :basename, &b) }.to yield_successive_args('/tmp/c/00.txt', '/tmp/b/01.txt', '/tmp/a/02.txt') }
|
751
751
|
end
|
752
752
|
|
@@ -55,8 +55,8 @@ describe Masamune::Schema::Catalog do
|
|
55
55
|
end
|
56
56
|
|
57
57
|
context '#load' do
|
58
|
-
let(:postgres_extra) { %w
|
59
|
-
let(:hive_extra) { %w
|
58
|
+
let(:postgres_extra) { %w[/tmp/schema.psql /tmp/00_schema.psql /tmp/20_schema.psql /tmp/40_schema.psql.erb] }
|
59
|
+
let(:hive_extra) { %w[/tmp/schema.hql /tmp/00_schema.hql /tmp/20_schema.hql /tmp/40_schema.hql.erb] }
|
60
60
|
let(:extra) { postgres_extra + hive_extra }
|
61
61
|
|
62
62
|
before do
|
@@ -322,7 +322,7 @@ describe Masamune::Schema::Catalog do
|
|
322
322
|
column 'user_id'
|
323
323
|
end
|
324
324
|
|
325
|
-
fact 'visits', grain: %w
|
325
|
+
fact 'visits', grain: %w[hourly daily monthly] do
|
326
326
|
references :user
|
327
327
|
measure 'count'
|
328
328
|
end
|
@@ -59,7 +59,7 @@ describe Masamune::Schema::Column do
|
|
59
59
|
end
|
60
60
|
|
61
61
|
context 'with type :enum' do
|
62
|
-
subject(:column) { described_class.new(id: 'mode', type: :enum, values: %w
|
62
|
+
subject(:column) { described_class.new(id: 'mode', type: :enum, values: %w[public private]) }
|
63
63
|
|
64
64
|
context '#default' do
|
65
65
|
subject { column.default }
|
@@ -81,7 +81,7 @@ describe Masamune::Schema::Column do
|
|
81
81
|
end
|
82
82
|
|
83
83
|
context 'with :default' do
|
84
|
-
subject(:column) { described_class.new(id: 'mode', type: :enum, values: %w
|
84
|
+
subject(:column) { described_class.new(id: 'mode', type: :enum, values: %w[public private], default: 'private') }
|
85
85
|
|
86
86
|
context '#default' do
|
87
87
|
subject { column.default }
|
@@ -123,7 +123,7 @@ describe Masamune::Schema::Column do
|
|
123
123
|
end
|
124
124
|
|
125
125
|
context 'with index: ["id", "shared"]' do
|
126
|
-
subject(:column) { described_class.new(id: 'id', index: %w
|
126
|
+
subject(:column) { described_class.new(id: 'id', index: %w[id shared]) }
|
127
127
|
context '#index' do
|
128
128
|
subject { column.index }
|
129
129
|
it { is_expected.to include(:id) }
|
@@ -210,7 +210,7 @@ describe Masamune::Schema::Column do
|
|
210
210
|
end
|
211
211
|
|
212
212
|
context 'with type :enum' do
|
213
|
-
let(:column) { described_class.new(id: 'enum', type: :enum, values: %w
|
213
|
+
let(:column) { described_class.new(id: 'enum', type: :enum, values: %w[public private]) }
|
214
214
|
context 'with enum value' do
|
215
215
|
let(:value) { 'public' }
|
216
216
|
it { is_expected.to eq("'public'::ENUM_TYPE") }
|
@@ -476,7 +476,7 @@ describe Masamune::Schema::Column do
|
|
476
476
|
|
477
477
|
context 'when array' do
|
478
478
|
let(:value) { '["1","2","3"]' }
|
479
|
-
it { is_expected.to eq(%w
|
479
|
+
it { is_expected.to eq(%w[1 2 3]) }
|
480
480
|
end
|
481
481
|
|
482
482
|
context 'when hash' do
|
@@ -494,7 +494,7 @@ describe Masamune::Schema::Column do
|
|
494
494
|
describe '#default_ruby_value' do
|
495
495
|
subject(:result) { column.default_ruby_value }
|
496
496
|
|
497
|
-
[
|
497
|
+
%i[boolean integer string].each do |type|
|
498
498
|
context "with type :#{type}" do
|
499
499
|
let(:column) { described_class.new(id: 'column', type: type) }
|
500
500
|
it { is_expected.to be_nil }
|
@@ -511,7 +511,7 @@ describe Masamune::Schema::Column do
|
|
511
511
|
it { is_expected.to eq(Time.new(0)) }
|
512
512
|
end
|
513
513
|
|
514
|
-
[
|
514
|
+
%i[json yaml key_value].each do |type|
|
515
515
|
context "with type :#{type}" do
|
516
516
|
let(:column) { described_class.new(id: 'column', type: type) }
|
517
517
|
it { is_expected.to eq({}) }
|
@@ -602,7 +602,7 @@ describe Masamune::Schema::Column do
|
|
602
602
|
end
|
603
603
|
|
604
604
|
context 'when array of string' do
|
605
|
-
let(:value) { %w
|
605
|
+
let(:value) { %w[1 2] }
|
606
606
|
it { is_expected.to eq('[1,2]') }
|
607
607
|
end
|
608
608
|
end
|
@@ -626,7 +626,7 @@ describe Masamune::Schema::Column do
|
|
626
626
|
end
|
627
627
|
|
628
628
|
context 'when array of string' do
|
629
|
-
let(:value) { %w
|
629
|
+
let(:value) { %w[1 2] }
|
630
630
|
it { is_expected.to eq('["1","2"]') }
|
631
631
|
end
|
632
632
|
|
@@ -70,8 +70,8 @@ describe Masamune::Schema::Table do
|
|
70
70
|
let(:table) do
|
71
71
|
described_class.new id: 'user',
|
72
72
|
columns: [
|
73
|
-
Masamune::Schema::Column.new(id: 'tenant_id', index: %w
|
74
|
-
Masamune::Schema::Column.new(id: 'user_id', index: %w
|
73
|
+
Masamune::Schema::Column.new(id: 'tenant_id', index: %w[tenant_id shared]),
|
74
|
+
Masamune::Schema::Column.new(id: 'user_id', index: %w[user_id shared])
|
75
75
|
]
|
76
76
|
end
|
77
77
|
|
@@ -83,7 +83,7 @@ describe Masamune::Schema::Table do
|
|
83
83
|
described_class.new id: 'user',
|
84
84
|
columns: [
|
85
85
|
Masamune::Schema::Column.new(id: 'tenant_id', unique: ['shared']),
|
86
|
-
Masamune::Schema::Column.new(id: 'user_id', unique: %w
|
86
|
+
Masamune::Schema::Column.new(id: 'user_id', unique: %w[user_id shared])
|
87
87
|
]
|
88
88
|
end
|
89
89
|
|
@@ -99,7 +99,7 @@ describe Masamune::Schema::Table do
|
|
99
99
|
columns: [
|
100
100
|
Masamune::Schema::Column.new(id: 'tenant_id'),
|
101
101
|
Masamune::Schema::Column.new(id: 'user_id'),
|
102
|
-
Masamune::Schema::Column.new(id: 'state', type: :enum, sub_type: :user_state, values: %w
|
102
|
+
Masamune::Schema::Column.new(id: 'state', type: :enum, sub_type: :user_state, values: %w[active inactive terminated], default: 'active')
|
103
103
|
]
|
104
104
|
end
|
105
105
|
|
@@ -324,22 +324,22 @@ describe Masamune::Schema::Table do
|
|
324
324
|
end
|
325
325
|
|
326
326
|
context 'with specified columns' do
|
327
|
-
subject(:stage_table) { table.stage_table(columns: %w
|
327
|
+
subject(:stage_table) { table.stage_table(columns: %w[id name user_account_state.id hr_user_account_state.id]) }
|
328
328
|
|
329
329
|
it 'should stage table' do
|
330
330
|
expect(stage_table.name).to eq('user_table_stage')
|
331
|
-
expect(stage_table.columns.keys).to eq([
|
332
|
-
expect(stage_table.references.keys).to eq([
|
331
|
+
expect(stage_table.columns.keys).to eq(%i[name user_account_state_table_id hr_user_account_state_table_id])
|
332
|
+
expect(stage_table.references.keys).to eq(%i[user_account_state hr_user_account_state])
|
333
333
|
end
|
334
334
|
end
|
335
335
|
|
336
336
|
context 'with specified columns (denormalized)' do
|
337
|
-
subject(:stage_table) { table.stage_table(columns: %w
|
337
|
+
subject(:stage_table) { table.stage_table(columns: %w[id name user_account_state.name hr_user_account_state.name]) }
|
338
338
|
|
339
339
|
it 'should stage table' do
|
340
340
|
expect(stage_table.name).to eq('user_table_stage')
|
341
|
-
expect(stage_table.columns.keys).to eq([
|
342
|
-
expect(stage_table.references.keys).to eq([
|
341
|
+
expect(stage_table.columns.keys).to eq(%i[name user_account_state_table_name hr_user_account_state_table_name])
|
342
|
+
expect(stage_table.references.keys).to eq(%i[user_account_state hr_user_account_state])
|
343
343
|
end
|
344
344
|
end
|
345
345
|
|
@@ -357,8 +357,8 @@ describe Masamune::Schema::Table do
|
|
357
357
|
|
358
358
|
it 'should stage table' do
|
359
359
|
expect(stage_table.name).to eq('user_table_stage')
|
360
|
-
expect(stage_table.columns.keys).to eq([
|
361
|
-
expect(stage_table.references.keys).to eq([
|
360
|
+
expect(stage_table.columns.keys).to eq(%i[name user_account_state_table_name hr_user_account_state_table_name])
|
361
|
+
expect(stage_table.references.keys).to eq(%i[user_account_state hr_user_account_state])
|
362
362
|
end
|
363
363
|
end
|
364
364
|
|
@@ -376,7 +376,7 @@ describe Masamune::Schema::Table do
|
|
376
376
|
|
377
377
|
it 'should stage table' do
|
378
378
|
expect(stage_table.name).to eq('user_table_stage')
|
379
|
-
expect(stage_table.columns.keys).to eq([
|
379
|
+
expect(stage_table.columns.keys).to eq(%i[user_id name hr_user_account_state_table_name])
|
380
380
|
expect(stage_table.references.keys).to eq([:hr_user_account_state])
|
381
381
|
end
|
382
382
|
end
|
@@ -396,7 +396,7 @@ describe Masamune::Schema::Table do
|
|
396
396
|
|
397
397
|
it 'should stage table' do
|
398
398
|
expect(stage_table.name).to eq('user_table_stage')
|
399
|
-
expect(stage_table.columns.keys).to eq([
|
399
|
+
expect(stage_table.columns.keys).to eq(%i[hr_user_account_state_table_id user_id name])
|
400
400
|
expect(stage_table.references.keys).to eq([:hr_user_account_state])
|
401
401
|
end
|
402
402
|
end
|
data/spec/masamune/thor_spec.rb
CHANGED
@@ -93,11 +93,11 @@ describe Masamune::Thor do
|
|
93
93
|
let(:command) { 'command' }
|
94
94
|
let(:options) { ['--version'] }
|
95
95
|
it 'exits with status code 0 and prints version' do
|
96
|
-
expect { execute_command }.to raise_error
|
96
|
+
expect { execute_command }.to raise_error do |e|
|
97
97
|
expect(e).to be_a(SystemExit)
|
98
98
|
expect(e.message).to eq('exit')
|
99
99
|
expect(e.status).to eq(0)
|
100
|
-
|
100
|
+
end
|
101
101
|
expect(stdout.string).to match(/\Amasamune/)
|
102
102
|
expect(stderr.string).to be_blank
|
103
103
|
end
|
@@ -199,11 +199,11 @@ describe Masamune::Thor do
|
|
199
199
|
let(:command) { 'unknown' }
|
200
200
|
let(:options) { ['--start', '2013-01-01'] }
|
201
201
|
it 'exits with status code 1 and prints error to stderr' do
|
202
|
-
expect { execute_command }.to raise_error
|
202
|
+
expect { execute_command }.to raise_error do |e|
|
203
203
|
expect(e).to be_a(SystemExit)
|
204
204
|
expect(e.message).to eq('Path :unknown_dir not defined')
|
205
205
|
expect(e.status).to eq(1)
|
206
|
-
|
206
|
+
end
|
207
207
|
expect(stdout.string).to be_blank
|
208
208
|
expect(stderr.string).to match(/Path :unknown_dir not defined/)
|
209
209
|
end
|
@@ -45,8 +45,8 @@ describe Masamune::Transform::DefineTable do
|
|
45
45
|
catalog.schema :hive do
|
46
46
|
dimension 'tenant', type: :ledger do
|
47
47
|
column 'tenant_id', type: :integer, natural_key: true
|
48
|
-
column 'tenant_account_state', type: :enum, values: %w
|
49
|
-
column 'tenant_premium_state', type: :enum, values: %w
|
48
|
+
column 'tenant_account_state', type: :enum, values: %w[missing unknown active inactive]
|
49
|
+
column 'tenant_premium_state', type: :enum, values: %w[missing unkown goodwill pilot sandbox premium internal free vmware]
|
50
50
|
column 'preferences', type: :key_value, null: true
|
51
51
|
end
|
52
52
|
end
|
@@ -81,8 +81,8 @@ describe Masamune::Transform::DefineTable do
|
|
81
81
|
partition :y
|
82
82
|
partition :m
|
83
83
|
column 'tenant_id', type: :integer, natural_key: true
|
84
|
-
column 'tenant_account_state', type: :enum, values: %w
|
85
|
-
column 'tenant_premium_state', type: :enum, values: %w
|
84
|
+
column 'tenant_account_state', type: :enum, values: %w[missing unknown active inactive]
|
85
|
+
column 'tenant_premium_state', type: :enum, values: %w[missing unkown goodwill pilot sandbox premium internal free vmware]
|
86
86
|
column 'preferences', type: :key_value, null: true
|
87
87
|
end
|
88
88
|
end
|
@@ -179,9 +179,9 @@ describe Masamune::Transform::DefineTable do
|
|
179
179
|
total INTEGER
|
180
180
|
);
|
181
181
|
|
182
|
-
COPY visits_file_fact_stage FROM 'output_1.csv' WITH (FORMAT 'csv', HEADER true);
|
183
|
-
COPY visits_file_fact_stage FROM 'output_2.csv' WITH (FORMAT 'csv', HEADER true);
|
184
|
-
COPY visits_file_fact_stage FROM 'output_3.csv' WITH (FORMAT 'csv', HEADER true);
|
182
|
+
\\COPY visits_file_fact_stage FROM 'output_1.csv' WITH (FORMAT 'csv', HEADER true);
|
183
|
+
\\COPY visits_file_fact_stage FROM 'output_2.csv' WITH (FORMAT 'csv', HEADER true);
|
184
|
+
\\COPY visits_file_fact_stage FROM 'output_3.csv' WITH (FORMAT 'csv', HEADER true);
|
185
185
|
|
186
186
|
CREATE INDEX visits_file_fact_stage_964dac1_index ON visits_file_fact_stage (date_dimension_date_id);
|
187
187
|
CREATE INDEX visits_file_fact_stage_5a187ed_index ON visits_file_fact_stage (feature_type_name);
|
@@ -101,8 +101,8 @@ describe Masamune::Transform::DefineTable do
|
|
101
101
|
before do
|
102
102
|
catalog.schema :postgres do
|
103
103
|
table 'user' do
|
104
|
-
column 'tenant_id', index: %w
|
105
|
-
column 'user_id', index: %w
|
104
|
+
column 'tenant_id', index: %w[tenant_id shared]
|
105
|
+
column 'user_id', index: %w[user_id shared]
|
106
106
|
end
|
107
107
|
end
|
108
108
|
end
|
@@ -146,7 +146,7 @@ describe Masamune::Transform::DefineTable do
|
|
146
146
|
catalog.schema :postgres do
|
147
147
|
table 'user' do
|
148
148
|
column 'tenant_id', unique: ['shared']
|
149
|
-
column 'user_id', unique: %w
|
149
|
+
column 'user_id', unique: %w[user_id shared]
|
150
150
|
end
|
151
151
|
end
|
152
152
|
end
|
@@ -381,7 +381,7 @@ describe Masamune::Transform::DefineTable do
|
|
381
381
|
table 'user' do
|
382
382
|
column 'tenant_id'
|
383
383
|
column 'user_id'
|
384
|
-
column 'state', type: :enum, sub_type: :user_state, values: %w
|
384
|
+
column 'state', type: :enum, sub_type: :user_state, values: %w[active inactive terminated], default: 'active'
|
385
385
|
end
|
386
386
|
end
|
387
387
|
end
|
@@ -724,7 +724,7 @@ describe Masamune::Transform::DefineTable do
|
|
724
724
|
end
|
725
725
|
|
726
726
|
context 'for postgres table with all specified columns' do
|
727
|
-
let(:columns) { %w
|
727
|
+
let(:columns) { %w[hr_user_account_state_table_id user_account_state_table_id name] }
|
728
728
|
|
729
729
|
it 'should render table template' do
|
730
730
|
is_expected.to eq <<-EOS.strip_heredoc
|
@@ -739,7 +739,7 @@ describe Masamune::Transform::DefineTable do
|
|
739
739
|
end
|
740
740
|
|
741
741
|
context 'for postgres table with all specified columns in denormalized form' do
|
742
|
-
let(:columns) { %w
|
742
|
+
let(:columns) { %w[hr_user_account_state.name user_account_state.name name] }
|
743
743
|
|
744
744
|
it 'should render table template' do
|
745
745
|
is_expected.to eq <<-EOS.strip_heredoc
|
@@ -311,8 +311,8 @@ describe Masamune::Transform::DenormalizeTable do
|
|
311
311
|
partition :y
|
312
312
|
partition :m
|
313
313
|
column 'tenant_id', type: :integer, natural_key: true
|
314
|
-
column 'tenant_account_state', type: :enum, values: %w
|
315
|
-
column 'tenant_premium_state', type: :enum, values: %w
|
314
|
+
column 'tenant_account_state', type: :enum, values: %w[missing unknown active inactive]
|
315
|
+
column 'tenant_premium_state', type: :enum, values: %w[missing unkown goodwill pilot sandbox premium internal free vmware]
|
316
316
|
column 'preferences', type: :key_value, null: true
|
317
317
|
end
|
318
318
|
end
|
@@ -322,18 +322,18 @@ describe Masamune::Transform::DenormalizeTable do
|
|
322
322
|
|
323
323
|
let(:options) do
|
324
324
|
{
|
325
|
-
columns: %w
|
325
|
+
columns: %w[
|
326
326
|
tenant_id
|
327
327
|
tenant_account_state
|
328
328
|
tenant_premium_state
|
329
329
|
preferences
|
330
330
|
y
|
331
331
|
m
|
332
|
-
|
333
|
-
order: %w
|
332
|
+
],
|
333
|
+
order: %w[
|
334
334
|
tenant_id
|
335
335
|
start_at
|
336
|
-
|
336
|
+
]
|
337
337
|
}
|
338
338
|
end
|
339
339
|
|
@@ -69,7 +69,7 @@ describe Masamune::Transform::RollupFact do
|
|
69
69
|
measure 'total', type: :integer, aggregate: :sum
|
70
70
|
end
|
71
71
|
|
72
|
-
fact 'visits', partition: 'y%Ym%m', grain: %w
|
72
|
+
fact 'visits', partition: 'y%Ym%m', grain: %w[hourly daily monthly] do
|
73
73
|
references :cluster
|
74
74
|
references :date
|
75
75
|
references :tenant
|
@@ -72,10 +72,10 @@ describe Masamune::Transform::StageFact do
|
|
72
72
|
row group_id: -2, group_mode: 'unknown', attributes: { id: :unknown }
|
73
73
|
end
|
74
74
|
|
75
|
-
fact 'visits', partition: 'y%Ym%m', grain: %w
|
75
|
+
fact 'visits', partition: 'y%Ym%m', grain: %w[hourly daily monthly] do
|
76
76
|
references :cluster
|
77
77
|
references :date
|
78
|
-
references :tenant, through: [
|
78
|
+
references :tenant, through: %i[user from_group group]
|
79
79
|
references :user
|
80
80
|
references :group, label: 'from', default: :missing, unknown: :unknown
|
81
81
|
references :group, default: :missing, unknown: :unknown
|
@@ -88,7 +88,7 @@ class Masamune::MockFilesystem < Delegator
|
|
88
88
|
true
|
89
89
|
end
|
90
90
|
|
91
|
-
[
|
91
|
+
%i[mkdir! copy_file_to_file copy_file_to_dir copy_dir remove_file remove_dir move_file_to_file move_file_to_dir move_dir write].each do |method|
|
92
92
|
define_method(method) do |*_args|
|
93
93
|
# Empty
|
94
94
|
end
|
@@ -119,7 +119,7 @@ module Masamune::SharedExampleGroup
|
|
119
119
|
if output['hive'] && output['hive'].is_a?(String)
|
120
120
|
hive(exec: output['hive'], output: output_file)
|
121
121
|
elsif output['table']
|
122
|
-
table = eval "catalog.#{output['table']}" # rubocop:disable
|
122
|
+
table = eval "catalog.#{output['table']}" # rubocop:disable Security/Eval
|
123
123
|
query = denormalize_table(table, output.slice('columns', 'order', 'except', 'include')).to_s
|
124
124
|
# FIXME: define format based on table.store.format
|
125
125
|
case table.store.type
|
@@ -34,10 +34,10 @@ module Masamune::TaskExampleGroup
|
|
34
34
|
|
35
35
|
shared_examples 'general usage' do
|
36
36
|
it 'exits with status code 0 and prints general usage' do
|
37
|
-
expect { execute_command }.to raise_error
|
37
|
+
expect { execute_command }.to raise_error do |e|
|
38
38
|
expect(e).to be_a(SystemExit)
|
39
39
|
expect(e.status).to eq(0)
|
40
|
-
|
40
|
+
end
|
41
41
|
expect(stdout.string).to match(/^Commands:/)
|
42
42
|
expect(stderr.string).to be_blank
|
43
43
|
end
|
@@ -45,10 +45,10 @@ module Masamune::TaskExampleGroup
|
|
45
45
|
|
46
46
|
shared_examples 'command usage' do
|
47
47
|
it 'exits with status code 0 and prints command usage' do
|
48
|
-
expect { execute_command }.to raise_error
|
48
|
+
expect { execute_command }.to raise_error do |e|
|
49
49
|
expect(e).to be_a(SystemExit)
|
50
50
|
expect(e.status).to eq(0)
|
51
|
-
|
51
|
+
end
|
52
52
|
expect(stdout.string).to match(/^Usage:/)
|
53
53
|
expect(stdout.string).to match(/^Options:/)
|
54
54
|
expect(stderr.string).to be_blank
|
@@ -57,10 +57,10 @@ module Masamune::TaskExampleGroup
|
|
57
57
|
|
58
58
|
shared_examples 'executes with success' do
|
59
59
|
it 'exits with status code 0' do
|
60
|
-
expect { execute_command }.to raise_error
|
60
|
+
expect { execute_command }.to raise_error do |e|
|
61
61
|
expect(e).to be_a(SystemExit)
|
62
62
|
expect(e.status).to eq(0)
|
63
|
-
|
63
|
+
end
|
64
64
|
end
|
65
65
|
end
|
66
66
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: masamune
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.19.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Michael Andrews
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-
|
11
|
+
date: 2017-05-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: thor
|
@@ -464,7 +464,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
464
464
|
version: '0'
|
465
465
|
requirements: []
|
466
466
|
rubyforge_project:
|
467
|
-
rubygems_version: 2.
|
467
|
+
rubygems_version: 2.4.8
|
468
468
|
signing_key:
|
469
469
|
specification_version: 4
|
470
470
|
summary: Hybrid Data & Work Flow
|