masamune 0.16.0 → 0.17.0

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: c8bcd874b8f53a052225b41043cfda18de823cec
4
- data.tar.gz: 9e4c71e47097a5035be079b92ce9d2698d74c7b4
3
+ metadata.gz: fed58d83f573640ea93aaee3226ba39e4b504302
4
+ data.tar.gz: a40fb42e8f9dd313c7606266424df457b61b5cef
5
5
  SHA512:
6
- metadata.gz: 8e4b65c5424fdf38915854a32299cc7825418f96798c63719619a8cc4bfd7a69d81e286006974b5660a03cb3b020a677b7db838cf5efa0f03d79ff4cac209053
7
- data.tar.gz: 8099dca87827675a761f9882025452d0c8bfd24773b09538006747e5b155d1ef9ec2f82a16bb16d5dc7b313aec748081d07541c332be5e633299c0dfeb88000c
6
+ metadata.gz: 1eef004f660f92fdb0664e65df4f402d0cf68059af223140fb3f33d5ad2a4c9a060543555d1cab548b46f4971e0fddc9ec4f1f2f48ee964ad596cc99dd6386c8
7
+ data.tar.gz: c07cd4e970b1208efcff02c052538590c9f8d27dbd53efaeedcd9845e7a19e37505954c2360d5835fb7588505e089378c7538549c4ada9cfe6fdcbc82a8bdd4d
@@ -22,11 +22,31 @@
22
22
 
23
23
  module Masamune::Schema
24
24
  class Dimension < Table
25
+ SUPPORTED_GRAINS = [:hourly, :daily, :monthly]
26
+
25
27
  def initialize(opts = {})
26
- super
28
+ opts.symbolize_keys!
29
+ self.grain = opts.delete(:grain)
30
+ super opts
27
31
  initialize_dimension_columns!
28
32
  end
29
33
 
34
+ def grain
35
+ return @grain if @grain
36
+ case type
37
+ when :date
38
+ :daily
39
+ else
40
+ :hourly
41
+ end
42
+ end
43
+
44
+ def grain=(grain = nil)
45
+ return unless grain
46
+ raise ArgumentError, "unknown grain '#{grain}'" unless SUPPORTED_GRAINS.include?(grain.to_sym)
47
+ @grain = grain.to_sym
48
+ end
49
+
30
50
  def suffix
31
51
  suffix = case type
32
52
  when :mini
@@ -22,12 +22,13 @@
22
22
 
23
23
  WITH consolidated AS (
24
24
  SELECT
25
- <%- target.insert_view_values(coalesce: true).each do |value| -%>
25
+ <%- target.insert_view_last_values('w').each do |value| -%>
26
26
  <%= value %><%= ',' %>
27
27
  <%- end -%>
28
- start_at
28
+ <%= target.start_at_with_grain %> AS start_at
29
29
  FROM
30
30
  <%= source.name %>
31
+ WINDOW w AS (PARTITION BY <%= target.window(target.start_at_with_grain).join(', ') %> ORDER BY start_at ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING)
31
32
  )
32
33
  INSERT INTO
33
34
  <%= target.name %> (<%= target.insert_columns.join(', ') %>, start_at)
@@ -42,12 +42,18 @@ module Masamune::Transform::Postgres
42
42
  consolidated_columns.map { |_, column| column.name }
43
43
  end
44
44
 
45
- def insert_view_values(coalesce: false)
45
+ def insert_view_values
46
46
  consolidated_columns.map do |_, column|
47
- if !column.default.nil? && coalesce
48
- "COALESCE(#{column.name}, #{column.sql_value(column.default)}) AS #{column.name}"
47
+ column.name
48
+ end
49
+ end
50
+
51
+ def insert_view_last_values(window)
52
+ consolidated_columns.map do |_, column|
53
+ if column.default.nil?
54
+ "LAST_VALUE(#{column.name}) OVER #{window} AS #{column.name}"
49
55
  else
50
- column.name
56
+ "COALESCE(LAST_VALUE(#{column.name}) OVER #{window}, #{column.sql_value(column.default)}) AS #{column.name}"
51
57
  end
52
58
  end
53
59
  end
@@ -68,6 +74,17 @@ module Masamune::Transform::Postgres
68
74
  (columns.values.select { |column| extra.delete(column.name) || column.natural_key || column.auto_reference }.map(&:name) + extra).uniq
69
75
  end
70
76
 
77
+ def start_at_with_grain
78
+ case grain
79
+ when :hourly
80
+ "date_trunc('hour', start_at)"
81
+ when :daily
82
+ "date_trunc('day', start_at)"
83
+ when :monthly
84
+ "date_trunc('month', start_at)"
85
+ end
86
+ end
87
+
71
88
  private
72
89
 
73
90
  def consolidated_columns
@@ -21,5 +21,5 @@
21
21
  # THE SOFTWARE.
22
22
 
23
23
  module Masamune
24
- VERSION = '0.16.0'
24
+ VERSION = '0.17.0'
25
25
  end
@@ -33,6 +33,7 @@ describe Masamune::Schema::Dimension do
33
33
 
34
34
  it { expect(dimension.name).to eq('date_dimension') }
35
35
  it { expect(dimension.type).to eq(:date) }
36
+ it { expect(dimension.grain).to eq(:daily) }
36
37
  end
37
38
 
38
39
  context 'for type :one' do
@@ -46,6 +47,7 @@ describe Masamune::Schema::Dimension do
46
47
 
47
48
  it { expect(dimension.name).to eq('user_dimension') }
48
49
  it { expect(dimension.type).to eq(:one) }
50
+ it { expect(dimension.grain).to eq(:hourly) }
49
51
  end
50
52
 
51
53
  context 'for type :two' do
@@ -59,6 +61,7 @@ describe Masamune::Schema::Dimension do
59
61
 
60
62
  it { expect(dimension.name).to eq('user_dimension') }
61
63
  it { expect(dimension.type).to eq(:two) }
64
+ it { expect(dimension.grain).to eq(:hourly) }
62
65
  end
63
66
 
64
67
  context 'with invalid values' do
@@ -106,6 +109,7 @@ describe Masamune::Schema::Dimension do
106
109
 
107
110
  it { expect(dimension.name).to eq('user_dimension') }
108
111
  it { expect(dimension.type).to eq(:four) }
112
+ it { expect(dimension.grain).to eq(:hourly) }
109
113
 
110
114
  describe '#stage_table' do
111
115
  let!(:stage_table) { dimension.stage_table }
@@ -132,4 +136,20 @@ describe Masamune::Schema::Dimension do
132
136
  end
133
137
  end
134
138
  end
139
+
140
+ context 'dimension with daily grain' do
141
+ let(:dimension) { described_class.new id: 'users', type: :one, grain: :daily }
142
+
143
+ it { expect(dimension.name).to eq('users_dimension') }
144
+ it { expect(dimension.type).to eq(:one) }
145
+ it { expect(dimension.grain).to eq(:daily) }
146
+ end
147
+
148
+ context 'dimension with unknown grain' do
149
+ subject(:dimension) do
150
+ described_class.new id: 'users', grain: :quarterly
151
+ end
152
+
153
+ it { expect { dimension }.to raise_error ArgumentError, "unknown grain 'quarterly'" }
154
+ end
135
155
  end
@@ -46,13 +46,14 @@ describe Masamune::Transform::DeduplicateDimension do
46
46
  is_expected.to eq <<-EOS.strip_heredoc
47
47
  WITH consolidated AS (
48
48
  SELECT
49
- user_account_state_type_id,
50
- tenant_id,
51
- user_id,
52
- preferences,
53
- start_at
49
+ LAST_VALUE(user_account_state_type_id) OVER w AS user_account_state_type_id,
50
+ LAST_VALUE(tenant_id) OVER w AS tenant_id,
51
+ LAST_VALUE(user_id) OVER w AS user_id,
52
+ LAST_VALUE(preferences) OVER w AS preferences,
53
+ date_trunc('hour', start_at) AS start_at
54
54
  FROM
55
55
  user_consolidated_dimension_stage
56
+ WINDOW w AS (PARTITION BY tenant_id, user_id, date_trunc('hour', start_at) ORDER BY start_at ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING)
56
57
  )
57
58
  INSERT INTO
58
59
  user_deduplicated_dimension_stage (user_account_state_type_id, tenant_id, user_id, preferences, start_at)
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.16.0
4
+ version: 0.17.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: 2016-01-21 00:00:00.000000000 Z
11
+ date: 2016-01-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: thor