masamune 0.11.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (185) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE.txt +21 -0
  3. data/README.md +54 -0
  4. data/Rakefile +15 -0
  5. data/bin/masamune-elastic-mapreduce +4 -0
  6. data/bin/masamune-hive +4 -0
  7. data/bin/masamune-psql +4 -0
  8. data/bin/masamune-shell +4 -0
  9. data/lib/masamune.rb +56 -0
  10. data/lib/masamune/accumulate.rb +60 -0
  11. data/lib/masamune/actions.rb +38 -0
  12. data/lib/masamune/actions/data_flow.rb +131 -0
  13. data/lib/masamune/actions/date_parse.rb +75 -0
  14. data/lib/masamune/actions/elastic_mapreduce.rb +68 -0
  15. data/lib/masamune/actions/execute.rb +52 -0
  16. data/lib/masamune/actions/filesystem.rb +37 -0
  17. data/lib/masamune/actions/hadoop_filesystem.rb +40 -0
  18. data/lib/masamune/actions/hadoop_streaming.rb +41 -0
  19. data/lib/masamune/actions/hive.rb +74 -0
  20. data/lib/masamune/actions/postgres.rb +76 -0
  21. data/lib/masamune/actions/postgres_admin.rb +34 -0
  22. data/lib/masamune/actions/s3cmd.rb +44 -0
  23. data/lib/masamune/actions/transform.rb +89 -0
  24. data/lib/masamune/after_initialize_callbacks.rb +55 -0
  25. data/lib/masamune/cached_filesystem.rb +110 -0
  26. data/lib/masamune/commands.rb +37 -0
  27. data/lib/masamune/commands/elastic_mapreduce.rb +119 -0
  28. data/lib/masamune/commands/hadoop_filesystem.rb +57 -0
  29. data/lib/masamune/commands/hadoop_streaming.rb +116 -0
  30. data/lib/masamune/commands/hive.rb +178 -0
  31. data/lib/masamune/commands/interactive.rb +37 -0
  32. data/lib/masamune/commands/postgres.rb +128 -0
  33. data/lib/masamune/commands/postgres_admin.rb +72 -0
  34. data/lib/masamune/commands/postgres_common.rb +33 -0
  35. data/lib/masamune/commands/retry_with_backoff.rb +60 -0
  36. data/lib/masamune/commands/s3cmd.rb +70 -0
  37. data/lib/masamune/commands/shell.rb +202 -0
  38. data/lib/masamune/configuration.rb +195 -0
  39. data/lib/masamune/data_plan.rb +31 -0
  40. data/lib/masamune/data_plan/builder.rb +66 -0
  41. data/lib/masamune/data_plan/elem.rb +190 -0
  42. data/lib/masamune/data_plan/engine.rb +162 -0
  43. data/lib/masamune/data_plan/rule.rb +292 -0
  44. data/lib/masamune/data_plan/set.rb +176 -0
  45. data/lib/masamune/environment.rb +164 -0
  46. data/lib/masamune/filesystem.rb +567 -0
  47. data/lib/masamune/has_environment.rb +40 -0
  48. data/lib/masamune/helpers.rb +27 -0
  49. data/lib/masamune/helpers/postgres.rb +84 -0
  50. data/lib/masamune/io.rb +33 -0
  51. data/lib/masamune/last_element.rb +53 -0
  52. data/lib/masamune/method_logger.rb +41 -0
  53. data/lib/masamune/multi_io.rb +39 -0
  54. data/lib/masamune/schema.rb +36 -0
  55. data/lib/masamune/schema/catalog.rb +233 -0
  56. data/lib/masamune/schema/column.rb +527 -0
  57. data/lib/masamune/schema/dimension.rb +133 -0
  58. data/lib/masamune/schema/event.rb +121 -0
  59. data/lib/masamune/schema/fact.rb +133 -0
  60. data/lib/masamune/schema/map.rb +265 -0
  61. data/lib/masamune/schema/row.rb +133 -0
  62. data/lib/masamune/schema/store.rb +115 -0
  63. data/lib/masamune/schema/table.rb +308 -0
  64. data/lib/masamune/schema/table_reference.rb +76 -0
  65. data/lib/masamune/spec_helper.rb +23 -0
  66. data/lib/masamune/string_format.rb +34 -0
  67. data/lib/masamune/tasks/elastic_mapreduce_thor.rb +60 -0
  68. data/lib/masamune/tasks/hive_thor.rb +55 -0
  69. data/lib/masamune/tasks/postgres_thor.rb +47 -0
  70. data/lib/masamune/tasks/shell_thor.rb +63 -0
  71. data/lib/masamune/template.rb +77 -0
  72. data/lib/masamune/thor.rb +186 -0
  73. data/lib/masamune/thor_loader.rb +38 -0
  74. data/lib/masamune/topological_hash.rb +34 -0
  75. data/lib/masamune/transform.rb +47 -0
  76. data/lib/masamune/transform/bulk_upsert.psql.erb +64 -0
  77. data/lib/masamune/transform/bulk_upsert.rb +52 -0
  78. data/lib/masamune/transform/consolidate_dimension.rb +54 -0
  79. data/lib/masamune/transform/deduplicate_dimension.psql.erb +52 -0
  80. data/lib/masamune/transform/deduplicate_dimension.rb +53 -0
  81. data/lib/masamune/transform/define_event_view.hql.erb +51 -0
  82. data/lib/masamune/transform/define_event_view.rb +60 -0
  83. data/lib/masamune/transform/define_index.psql.erb +34 -0
  84. data/lib/masamune/transform/define_schema.hql.erb +23 -0
  85. data/lib/masamune/transform/define_schema.psql.erb +79 -0
  86. data/lib/masamune/transform/define_schema.rb +56 -0
  87. data/lib/masamune/transform/define_table.hql.erb +34 -0
  88. data/lib/masamune/transform/define_table.psql.erb +95 -0
  89. data/lib/masamune/transform/define_table.rb +40 -0
  90. data/lib/masamune/transform/define_unique.psql.erb +30 -0
  91. data/lib/masamune/transform/insert_reference_values.psql.erb +43 -0
  92. data/lib/masamune/transform/insert_reference_values.rb +64 -0
  93. data/lib/masamune/transform/load_dimension.rb +47 -0
  94. data/lib/masamune/transform/load_fact.rb +45 -0
  95. data/lib/masamune/transform/operator.rb +96 -0
  96. data/lib/masamune/transform/relabel_dimension.psql.erb +76 -0
  97. data/lib/masamune/transform/relabel_dimension.rb +39 -0
  98. data/lib/masamune/transform/rollup_fact.psql.erb +79 -0
  99. data/lib/masamune/transform/rollup_fact.rb +149 -0
  100. data/lib/masamune/transform/snapshot_dimension.psql.erb +75 -0
  101. data/lib/masamune/transform/snapshot_dimension.rb +74 -0
  102. data/lib/masamune/transform/stage_dimension.psql.erb +39 -0
  103. data/lib/masamune/transform/stage_dimension.rb +83 -0
  104. data/lib/masamune/transform/stage_fact.psql.erb +80 -0
  105. data/lib/masamune/transform/stage_fact.rb +111 -0
  106. data/lib/masamune/version.rb +25 -0
  107. data/spec/fixtures/aggregate.sql.erb +25 -0
  108. data/spec/fixtures/comment.sql.erb +27 -0
  109. data/spec/fixtures/invalid.sql.erb +23 -0
  110. data/spec/fixtures/relative.sql.erb +23 -0
  111. data/spec/fixtures/simple.sql.erb +28 -0
  112. data/spec/fixtures/whitespace.sql.erb +30 -0
  113. data/spec/masamune/actions/elastic_mapreduce_spec.rb +108 -0
  114. data/spec/masamune/actions/execute_spec.rb +50 -0
  115. data/spec/masamune/actions/hadoop_filesystem_spec.rb +44 -0
  116. data/spec/masamune/actions/hadoop_streaming_spec.rb +74 -0
  117. data/spec/masamune/actions/hive_spec.rb +117 -0
  118. data/spec/masamune/actions/postgres_admin_spec.rb +58 -0
  119. data/spec/masamune/actions/postgres_spec.rb +134 -0
  120. data/spec/masamune/actions/s3cmd_spec.rb +44 -0
  121. data/spec/masamune/actions/transform_spec.rb +144 -0
  122. data/spec/masamune/after_initialization_callbacks_spec.rb +61 -0
  123. data/spec/masamune/cached_filesystem_spec.rb +167 -0
  124. data/spec/masamune/commands/hadoop_filesystem_spec.rb +50 -0
  125. data/spec/masamune/commands/hadoop_streaming_spec.rb +106 -0
  126. data/spec/masamune/commands/hive_spec.rb +117 -0
  127. data/spec/masamune/commands/postgres_admin_spec.rb +69 -0
  128. data/spec/masamune/commands/postgres_spec.rb +100 -0
  129. data/spec/masamune/commands/retry_with_backoff_spec.rb +116 -0
  130. data/spec/masamune/commands/s3cmd_spec.rb +50 -0
  131. data/spec/masamune/commands/shell_spec.rb +101 -0
  132. data/spec/masamune/configuration_spec.rb +102 -0
  133. data/spec/masamune/data_plan/builder_spec.rb +91 -0
  134. data/spec/masamune/data_plan/elem_spec.rb +102 -0
  135. data/spec/masamune/data_plan/engine_spec.rb +356 -0
  136. data/spec/masamune/data_plan/rule_spec.rb +407 -0
  137. data/spec/masamune/data_plan/set_spec.rb +517 -0
  138. data/spec/masamune/environment_spec.rb +65 -0
  139. data/spec/masamune/filesystem_spec.rb +1421 -0
  140. data/spec/masamune/helpers/postgres_spec.rb +95 -0
  141. data/spec/masamune/schema/catalog_spec.rb +613 -0
  142. data/spec/masamune/schema/column_spec.rb +696 -0
  143. data/spec/masamune/schema/dimension_spec.rb +137 -0
  144. data/spec/masamune/schema/event_spec.rb +75 -0
  145. data/spec/masamune/schema/fact_spec.rb +117 -0
  146. data/spec/masamune/schema/map_spec.rb +593 -0
  147. data/spec/masamune/schema/row_spec.rb +28 -0
  148. data/spec/masamune/schema/store_spec.rb +49 -0
  149. data/spec/masamune/schema/table_spec.rb +395 -0
  150. data/spec/masamune/string_format_spec.rb +60 -0
  151. data/spec/masamune/tasks/elastic_mapreduce_thor_spec.rb +57 -0
  152. data/spec/masamune/tasks/hive_thor_spec.rb +75 -0
  153. data/spec/masamune/tasks/postgres_thor_spec.rb +42 -0
  154. data/spec/masamune/tasks/shell_thor_spec.rb +51 -0
  155. data/spec/masamune/template_spec.rb +77 -0
  156. data/spec/masamune/thor_spec.rb +238 -0
  157. data/spec/masamune/transform/bulk_upsert.dimension_spec.rb +200 -0
  158. data/spec/masamune/transform/consolidate_dimension_spec.rb +62 -0
  159. data/spec/masamune/transform/deduplicate_dimension_spec.rb +84 -0
  160. data/spec/masamune/transform/define_event_view_spec.rb +84 -0
  161. data/spec/masamune/transform/define_schema_spec.rb +83 -0
  162. data/spec/masamune/transform/define_table.dimension_spec.rb +306 -0
  163. data/spec/masamune/transform/define_table.fact_spec.rb +291 -0
  164. data/spec/masamune/transform/define_table.table_spec.rb +525 -0
  165. data/spec/masamune/transform/insert_reference_values.dimension_spec.rb +111 -0
  166. data/spec/masamune/transform/insert_reference_values.fact_spec.rb +149 -0
  167. data/spec/masamune/transform/load_dimension_spec.rb +76 -0
  168. data/spec/masamune/transform/load_fact_spec.rb +89 -0
  169. data/spec/masamune/transform/relabel_dimension_spec.rb +102 -0
  170. data/spec/masamune/transform/rollup_fact_spec.rb +333 -0
  171. data/spec/masamune/transform/snapshot_dimension_spec.rb +103 -0
  172. data/spec/masamune/transform/stage_dimension_spec.rb +115 -0
  173. data/spec/masamune/transform/stage_fact_spec.rb +204 -0
  174. data/spec/masamune_spec.rb +32 -0
  175. data/spec/spec_helper.rb +41 -0
  176. data/spec/support/masamune/example_group.rb +36 -0
  177. data/spec/support/masamune/mock_command.rb +99 -0
  178. data/spec/support/masamune/mock_delegate.rb +51 -0
  179. data/spec/support/masamune/mock_filesystem.rb +96 -0
  180. data/spec/support/masamune/thor_mute.rb +35 -0
  181. data/spec/support/rspec/example/action_example_group.rb +34 -0
  182. data/spec/support/rspec/example/task_example_group.rb +80 -0
  183. data/spec/support/rspec/example/transform_example_group.rb +36 -0
  184. data/spec/support/shared_examples/postgres_common_examples.rb +53 -0
  185. metadata +462 -0
@@ -0,0 +1,333 @@
1
+ # The MIT License (MIT)
2
+ #
3
+ # Copyright (c) 2014-2015, VMware, Inc. All Rights Reserved.
4
+ #
5
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ # of this software and associated documentation files (the "Software"), to deal
7
+ # in the Software without restriction, including without limitation the rights
8
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ # copies of the Software, and to permit persons to whom the Software is
10
+ # furnished to do so, subject to the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be included in
13
+ # all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ # THE SOFTWARE.
22
+
23
+ require 'spec_helper'
24
+
25
+ describe Masamune::Transform::RollupFact do
26
+ before do
27
+ catalog.schema :postgres do
28
+ dimension 'cluster', type: :mini do
29
+ column 'id', type: :sequence, surrogate_key: true, auto: true
30
+ column 'name', type: :string
31
+
32
+ row name: 'current_database()', attributes: {default: true}
33
+ end
34
+
35
+ dimension 'date', type: :date do
36
+ column 'date_id', type: :integer, unique: true, index: true, natural_key: true
37
+ column 'date_epoch', type: :integer
38
+ column 'month_epoch', type: :integer
39
+ column 'year_epoch', type: :integer
40
+ end
41
+
42
+ dimension 'user_agent', type: :mini do
43
+ column 'name', type: :string, unique: true, index: 'shared'
44
+ column 'version', type: :string, unique: true, index: 'shared', default: 'Unknown'
45
+ column 'description', type: :string, null: true, ignore: true
46
+ end
47
+
48
+ dimension 'feature', type: :mini do
49
+ column 'name', type: :string, unique: true, index: true
50
+ end
51
+
52
+ dimension 'tenant', type: :two do
53
+ column 'tenant_id', type: :integer, index: true, natural_key: true
54
+ end
55
+
56
+ dimension 'user', type: :two do
57
+ column 'tenant_id', type: :integer, index: true, natural_key: true
58
+ column 'user_id', type: :integer, index: true, natural_key: true
59
+ end
60
+
61
+ fact 'visits', partition: 'y%Ym%m', grain: 'transaction' do
62
+ references :cluster
63
+ references :date
64
+ references :tenant
65
+ references :user
66
+ references :user_agent, insert: true
67
+ references :feature, insert: true
68
+ references :session, degenerate: true
69
+ measure 'total', type: :integer, aggregate: :sum
70
+ end
71
+
72
+ fact 'visits', partition: 'y%Ym%m', grain: %w(hourly daily monthly) do
73
+ references :cluster
74
+ references :date
75
+ references :tenant
76
+ references :user
77
+ references :user_agent, insert: true
78
+ references :feature, insert: true
79
+ measure 'total', type: :integer, aggregate: :sum
80
+ end
81
+ end
82
+ end
83
+
84
+ context 'with postgres transaction fact' do
85
+ let(:date) { DateTime.civil(2014,8) }
86
+ let(:source) { catalog.postgres.visits_transaction_fact }
87
+ let(:target) { catalog.postgres.visits_hourly_fact }
88
+
89
+ subject(:result) { transform.rollup_fact(source, target, date).to_s }
90
+
91
+ it 'should eq render rollup_fact template' do
92
+ is_expected.to eq <<-EOS.strip_heredoc
93
+ BEGIN;
94
+
95
+ DROP TABLE IF EXISTS visits_hourly_fact_y2014m08_stage CASCADE;
96
+ CREATE TABLE IF NOT EXISTS visits_hourly_fact_y2014m08_stage (LIKE visits_hourly_fact INCLUDING ALL);
97
+
98
+ ALTER TABLE visits_hourly_fact_y2014m08_stage ADD CONSTRAINT visits_hourly_fact_y2014m08_stage_time_key_check CHECK (time_key >= 1406851200 AND time_key < 1409529600);
99
+ ALTER TABLE visits_hourly_fact_y2014m08_stage ADD CONSTRAINT visits_hourly_fact_y2014m08_stage_cluster_type_id_fkey FOREIGN KEY (cluster_type_id) REFERENCES cluster_type(id);
100
+ ALTER TABLE visits_hourly_fact_y2014m08_stage ADD CONSTRAINT visits_hourly_fact_y2014m08_stage_date_dimension_id_fkey FOREIGN KEY (date_dimension_id) REFERENCES date_dimension(id);
101
+ ALTER TABLE visits_hourly_fact_y2014m08_stage ADD CONSTRAINT visits_hourly_fact_y2014m08_stage_tenant_dimension_id_fkey FOREIGN KEY (tenant_dimension_id) REFERENCES tenant_dimension(id);
102
+ ALTER TABLE visits_hourly_fact_y2014m08_stage ADD CONSTRAINT visits_hourly_fact_y2014m08_stage_user_dimension_id_fkey FOREIGN KEY (user_dimension_id) REFERENCES user_dimension(id);
103
+ ALTER TABLE visits_hourly_fact_y2014m08_stage ADD CONSTRAINT visits_hourly_fact_y2014m08_stage_user_agent_type_id_fkey FOREIGN KEY (user_agent_type_id) REFERENCES user_agent_type(id);
104
+ ALTER TABLE visits_hourly_fact_y2014m08_stage ADD CONSTRAINT visits_hourly_fact_y2014m08_stage_feature_type_id_fkey FOREIGN KEY (feature_type_id) REFERENCES feature_type(id);
105
+
106
+ INSERT INTO
107
+ visits_hourly_fact_y2014m08_stage (date_dimension_id, tenant_dimension_id, user_dimension_id, user_agent_type_id, feature_type_id, total, time_key)
108
+ SELECT
109
+ (SELECT id FROM date_dimension d WHERE d.date_epoch = date_dimension.date_epoch ORDER BY d.date_id LIMIT 1),
110
+ visits_transaction_fact_y2014m08.tenant_dimension_id,
111
+ visits_transaction_fact_y2014m08.user_dimension_id,
112
+ visits_transaction_fact_y2014m08.user_agent_type_id,
113
+ visits_transaction_fact_y2014m08.feature_type_id,
114
+ SUM(visits_transaction_fact_y2014m08.total),
115
+ (visits_transaction_fact_y2014m08.time_key - (visits_transaction_fact_y2014m08.time_key % 3600))
116
+ FROM
117
+ visits_transaction_fact_y2014m08
118
+ JOIN
119
+ date_dimension
120
+ ON
121
+ date_dimension.id = visits_transaction_fact_y2014m08.date_dimension_id
122
+ GROUP BY
123
+ date_dimension.date_epoch,
124
+ visits_transaction_fact_y2014m08.tenant_dimension_id,
125
+ visits_transaction_fact_y2014m08.user_dimension_id,
126
+ visits_transaction_fact_y2014m08.user_agent_type_id,
127
+ visits_transaction_fact_y2014m08.feature_type_id,
128
+ (visits_transaction_fact_y2014m08.time_key - (visits_transaction_fact_y2014m08.time_key % 3600))
129
+ ;
130
+
131
+ CREATE INDEX visits_hourly_fact_y2014m08_stage_cluster_type_id_index ON visits_hourly_fact_y2014m08_stage (cluster_type_id);
132
+ CREATE INDEX visits_hourly_fact_y2014m08_stage_date_dimension_id_index ON visits_hourly_fact_y2014m08_stage (date_dimension_id);
133
+ CREATE INDEX visits_hourly_fact_y2014m08_stage_tenant_dimension_id_index ON visits_hourly_fact_y2014m08_stage (tenant_dimension_id);
134
+ CREATE INDEX visits_hourly_fact_y2014m08_stage_user_dimension_id_index ON visits_hourly_fact_y2014m08_stage (user_dimension_id);
135
+ CREATE INDEX visits_hourly_fact_y2014m08_stage_user_agent_type_id_index ON visits_hourly_fact_y2014m08_stage (user_agent_type_id);
136
+ CREATE INDEX visits_hourly_fact_y2014m08_stage_feature_type_id_index ON visits_hourly_fact_y2014m08_stage (feature_type_id);
137
+ CREATE INDEX visits_hourly_fact_y2014m08_stage_time_key_index ON visits_hourly_fact_y2014m08_stage (time_key);
138
+
139
+ COMMIT;
140
+
141
+ BEGIN;
142
+
143
+ DROP TABLE IF EXISTS visits_hourly_fact_y2014m08;
144
+ ALTER TABLE visits_hourly_fact_y2014m08_stage RENAME TO visits_hourly_fact_y2014m08;
145
+
146
+ ALTER TABLE visits_hourly_fact_y2014m08 INHERIT visits_hourly_fact;
147
+ ALTER TABLE visits_hourly_fact_y2014m08 ADD CONSTRAINT visits_hourly_fact_y2014m08_time_key_check CHECK (time_key >= 1406851200 AND time_key < 1409529600) NOT VALID;
148
+ ALTER TABLE visits_hourly_fact_y2014m08 ADD CONSTRAINT visits_hourly_fact_y2014m08_cluster_type_id_fkey FOREIGN KEY (cluster_type_id) REFERENCES cluster_type(id) NOT VALID;
149
+ ALTER TABLE visits_hourly_fact_y2014m08 ADD CONSTRAINT visits_hourly_fact_y2014m08_date_dimension_id_fkey FOREIGN KEY (date_dimension_id) REFERENCES date_dimension(id) NOT VALID;
150
+ ALTER TABLE visits_hourly_fact_y2014m08 ADD CONSTRAINT visits_hourly_fact_y2014m08_tenant_dimension_id_fkey FOREIGN KEY (tenant_dimension_id) REFERENCES tenant_dimension(id) NOT VALID;
151
+ ALTER TABLE visits_hourly_fact_y2014m08 ADD CONSTRAINT visits_hourly_fact_y2014m08_user_dimension_id_fkey FOREIGN KEY (user_dimension_id) REFERENCES user_dimension(id) NOT VALID;
152
+ ALTER TABLE visits_hourly_fact_y2014m08 ADD CONSTRAINT visits_hourly_fact_y2014m08_user_agent_type_id_fkey FOREIGN KEY (user_agent_type_id) REFERENCES user_agent_type(id) NOT VALID;
153
+ ALTER TABLE visits_hourly_fact_y2014m08 ADD CONSTRAINT visits_hourly_fact_y2014m08_feature_type_id_fkey FOREIGN KEY (feature_type_id) REFERENCES feature_type(id) NOT VALID;
154
+
155
+ ALTER INDEX visits_hourly_fact_y2014m08_stage_cluster_type_id_index RENAME TO visits_hourly_fact_y2014m08_cluster_type_id_index;
156
+ ALTER INDEX visits_hourly_fact_y2014m08_stage_date_dimension_id_index RENAME TO visits_hourly_fact_y2014m08_date_dimension_id_index;
157
+ ALTER INDEX visits_hourly_fact_y2014m08_stage_tenant_dimension_id_index RENAME TO visits_hourly_fact_y2014m08_tenant_dimension_id_index;
158
+ ALTER INDEX visits_hourly_fact_y2014m08_stage_user_dimension_id_index RENAME TO visits_hourly_fact_y2014m08_user_dimension_id_index;
159
+ ALTER INDEX visits_hourly_fact_y2014m08_stage_user_agent_type_id_index RENAME TO visits_hourly_fact_y2014m08_user_agent_type_id_index;
160
+ ALTER INDEX visits_hourly_fact_y2014m08_stage_feature_type_id_index RENAME TO visits_hourly_fact_y2014m08_feature_type_id_index;
161
+ ALTER INDEX visits_hourly_fact_y2014m08_stage_time_key_index RENAME TO visits_hourly_fact_y2014m08_time_key_index;
162
+
163
+ COMMIT;
164
+ EOS
165
+ end
166
+ end
167
+
168
+ context 'with postgres hourly fact' do
169
+ let(:date) { DateTime.civil(2014,8) }
170
+ let(:source) { catalog.postgres.visits_hourly_fact }
171
+ let(:target) { catalog.postgres.visits_daily_fact }
172
+
173
+ subject(:result) { transform.rollup_fact(source, target, date).to_s }
174
+
175
+ it 'should eq render rollup_fact template' do
176
+ is_expected.to eq <<-EOS.strip_heredoc
177
+ BEGIN;
178
+
179
+ DROP TABLE IF EXISTS visits_daily_fact_y2014m08_stage CASCADE;
180
+ CREATE TABLE IF NOT EXISTS visits_daily_fact_y2014m08_stage (LIKE visits_daily_fact INCLUDING ALL);
181
+
182
+ ALTER TABLE visits_daily_fact_y2014m08_stage ADD CONSTRAINT visits_daily_fact_y2014m08_stage_time_key_check CHECK (time_key >= 1406851200 AND time_key < 1409529600);
183
+ ALTER TABLE visits_daily_fact_y2014m08_stage ADD CONSTRAINT visits_daily_fact_y2014m08_stage_cluster_type_id_fkey FOREIGN KEY (cluster_type_id) REFERENCES cluster_type(id);
184
+ ALTER TABLE visits_daily_fact_y2014m08_stage ADD CONSTRAINT visits_daily_fact_y2014m08_stage_date_dimension_id_fkey FOREIGN KEY (date_dimension_id) REFERENCES date_dimension(id);
185
+ ALTER TABLE visits_daily_fact_y2014m08_stage ADD CONSTRAINT visits_daily_fact_y2014m08_stage_tenant_dimension_id_fkey FOREIGN KEY (tenant_dimension_id) REFERENCES tenant_dimension(id);
186
+ ALTER TABLE visits_daily_fact_y2014m08_stage ADD CONSTRAINT visits_daily_fact_y2014m08_stage_user_dimension_id_fkey FOREIGN KEY (user_dimension_id) REFERENCES user_dimension(id);
187
+ ALTER TABLE visits_daily_fact_y2014m08_stage ADD CONSTRAINT visits_daily_fact_y2014m08_stage_user_agent_type_id_fkey FOREIGN KEY (user_agent_type_id) REFERENCES user_agent_type(id);
188
+ ALTER TABLE visits_daily_fact_y2014m08_stage ADD CONSTRAINT visits_daily_fact_y2014m08_stage_feature_type_id_fkey FOREIGN KEY (feature_type_id) REFERENCES feature_type(id);
189
+
190
+ INSERT INTO
191
+ visits_daily_fact_y2014m08_stage (date_dimension_id, tenant_dimension_id, user_dimension_id, user_agent_type_id, feature_type_id, total, time_key)
192
+ SELECT
193
+ (SELECT id FROM date_dimension d WHERE d.date_epoch = date_dimension.date_epoch ORDER BY d.date_id LIMIT 1),
194
+ visits_hourly_fact_y2014m08.tenant_dimension_id,
195
+ visits_hourly_fact_y2014m08.user_dimension_id,
196
+ visits_hourly_fact_y2014m08.user_agent_type_id,
197
+ visits_hourly_fact_y2014m08.feature_type_id,
198
+ SUM(visits_hourly_fact_y2014m08.total),
199
+ (SELECT date_epoch FROM date_dimension d WHERE d.date_epoch = date_dimension.date_epoch ORDER BY d.date_id LIMIT 1)
200
+ FROM
201
+ visits_hourly_fact_y2014m08
202
+ JOIN
203
+ date_dimension
204
+ ON
205
+ date_dimension.id = visits_hourly_fact_y2014m08.date_dimension_id
206
+ GROUP BY
207
+ date_dimension.date_epoch,
208
+ visits_hourly_fact_y2014m08.tenant_dimension_id,
209
+ visits_hourly_fact_y2014m08.user_dimension_id,
210
+ visits_hourly_fact_y2014m08.user_agent_type_id,
211
+ visits_hourly_fact_y2014m08.feature_type_id
212
+ ;
213
+
214
+ CREATE INDEX visits_daily_fact_y2014m08_stage_cluster_type_id_index ON visits_daily_fact_y2014m08_stage (cluster_type_id);
215
+ CREATE INDEX visits_daily_fact_y2014m08_stage_date_dimension_id_index ON visits_daily_fact_y2014m08_stage (date_dimension_id);
216
+ CREATE INDEX visits_daily_fact_y2014m08_stage_tenant_dimension_id_index ON visits_daily_fact_y2014m08_stage (tenant_dimension_id);
217
+ CREATE INDEX visits_daily_fact_y2014m08_stage_user_dimension_id_index ON visits_daily_fact_y2014m08_stage (user_dimension_id);
218
+ CREATE INDEX visits_daily_fact_y2014m08_stage_user_agent_type_id_index ON visits_daily_fact_y2014m08_stage (user_agent_type_id);
219
+ CREATE INDEX visits_daily_fact_y2014m08_stage_feature_type_id_index ON visits_daily_fact_y2014m08_stage (feature_type_id);
220
+ CREATE INDEX visits_daily_fact_y2014m08_stage_time_key_index ON visits_daily_fact_y2014m08_stage (time_key);
221
+
222
+ COMMIT;
223
+
224
+ BEGIN;
225
+
226
+ DROP TABLE IF EXISTS visits_daily_fact_y2014m08;
227
+ ALTER TABLE visits_daily_fact_y2014m08_stage RENAME TO visits_daily_fact_y2014m08;
228
+
229
+ ALTER TABLE visits_daily_fact_y2014m08 INHERIT visits_daily_fact;
230
+ ALTER TABLE visits_daily_fact_y2014m08 ADD CONSTRAINT visits_daily_fact_y2014m08_time_key_check CHECK (time_key >= 1406851200 AND time_key < 1409529600) NOT VALID;
231
+ ALTER TABLE visits_daily_fact_y2014m08 ADD CONSTRAINT visits_daily_fact_y2014m08_cluster_type_id_fkey FOREIGN KEY (cluster_type_id) REFERENCES cluster_type(id) NOT VALID;
232
+ ALTER TABLE visits_daily_fact_y2014m08 ADD CONSTRAINT visits_daily_fact_y2014m08_date_dimension_id_fkey FOREIGN KEY (date_dimension_id) REFERENCES date_dimension(id) NOT VALID;
233
+ ALTER TABLE visits_daily_fact_y2014m08 ADD CONSTRAINT visits_daily_fact_y2014m08_tenant_dimension_id_fkey FOREIGN KEY (tenant_dimension_id) REFERENCES tenant_dimension(id) NOT VALID;
234
+ ALTER TABLE visits_daily_fact_y2014m08 ADD CONSTRAINT visits_daily_fact_y2014m08_user_dimension_id_fkey FOREIGN KEY (user_dimension_id) REFERENCES user_dimension(id) NOT VALID;
235
+ ALTER TABLE visits_daily_fact_y2014m08 ADD CONSTRAINT visits_daily_fact_y2014m08_user_agent_type_id_fkey FOREIGN KEY (user_agent_type_id) REFERENCES user_agent_type(id) NOT VALID;
236
+ ALTER TABLE visits_daily_fact_y2014m08 ADD CONSTRAINT visits_daily_fact_y2014m08_feature_type_id_fkey FOREIGN KEY (feature_type_id) REFERENCES feature_type(id) NOT VALID;
237
+
238
+ ALTER INDEX visits_daily_fact_y2014m08_stage_cluster_type_id_index RENAME TO visits_daily_fact_y2014m08_cluster_type_id_index;
239
+ ALTER INDEX visits_daily_fact_y2014m08_stage_date_dimension_id_index RENAME TO visits_daily_fact_y2014m08_date_dimension_id_index;
240
+ ALTER INDEX visits_daily_fact_y2014m08_stage_tenant_dimension_id_index RENAME TO visits_daily_fact_y2014m08_tenant_dimension_id_index;
241
+ ALTER INDEX visits_daily_fact_y2014m08_stage_user_dimension_id_index RENAME TO visits_daily_fact_y2014m08_user_dimension_id_index;
242
+ ALTER INDEX visits_daily_fact_y2014m08_stage_user_agent_type_id_index RENAME TO visits_daily_fact_y2014m08_user_agent_type_id_index;
243
+ ALTER INDEX visits_daily_fact_y2014m08_stage_feature_type_id_index RENAME TO visits_daily_fact_y2014m08_feature_type_id_index;
244
+ ALTER INDEX visits_daily_fact_y2014m08_stage_time_key_index RENAME TO visits_daily_fact_y2014m08_time_key_index;
245
+
246
+ COMMIT;
247
+ EOS
248
+ end
249
+ end
250
+
251
+ context 'with postgres daily fact' do
252
+ let(:date) { DateTime.civil(2014,8) }
253
+ let(:source) { catalog.postgres.visits_daily_fact }
254
+ let(:target) { catalog.postgres.visits_monthly_fact }
255
+
256
+ subject(:result) { transform.rollup_fact(source, target, date).to_s }
257
+
258
+ it 'should eq render rollup_fact template' do
259
+ is_expected.to eq <<-EOS.strip_heredoc
260
+ BEGIN;
261
+
262
+ DROP TABLE IF EXISTS visits_monthly_fact_y2014m08_stage CASCADE;
263
+ CREATE TABLE IF NOT EXISTS visits_monthly_fact_y2014m08_stage (LIKE visits_monthly_fact INCLUDING ALL);
264
+
265
+ ALTER TABLE visits_monthly_fact_y2014m08_stage ADD CONSTRAINT visits_monthly_fact_y2014m08_stage_time_key_check CHECK (time_key >= 1406851200 AND time_key < 1409529600);
266
+ ALTER TABLE visits_monthly_fact_y2014m08_stage ADD CONSTRAINT visits_monthly_fact_y2014m08_stage_cluster_type_id_fkey FOREIGN KEY (cluster_type_id) REFERENCES cluster_type(id);
267
+ ALTER TABLE visits_monthly_fact_y2014m08_stage ADD CONSTRAINT visits_monthly_fact_y2014m08_stage_date_dimension_id_fkey FOREIGN KEY (date_dimension_id) REFERENCES date_dimension(id);
268
+ ALTER TABLE visits_monthly_fact_y2014m08_stage ADD CONSTRAINT visits_monthly_fact_y2014m08_stage_tenant_dimension_id_fkey FOREIGN KEY (tenant_dimension_id) REFERENCES tenant_dimension(id);
269
+ ALTER TABLE visits_monthly_fact_y2014m08_stage ADD CONSTRAINT visits_monthly_fact_y2014m08_stage_user_dimension_id_fkey FOREIGN KEY (user_dimension_id) REFERENCES user_dimension(id);
270
+ ALTER TABLE visits_monthly_fact_y2014m08_stage ADD CONSTRAINT visits_monthly_fact_y2014m08_stage_user_agent_type_id_fkey FOREIGN KEY (user_agent_type_id) REFERENCES user_agent_type(id);
271
+ ALTER TABLE visits_monthly_fact_y2014m08_stage ADD CONSTRAINT visits_monthly_fact_y2014m08_stage_feature_type_id_fkey FOREIGN KEY (feature_type_id) REFERENCES feature_type(id);
272
+
273
+ INSERT INTO
274
+ visits_monthly_fact_y2014m08_stage (date_dimension_id, tenant_dimension_id, user_dimension_id, user_agent_type_id, feature_type_id, total, time_key)
275
+ SELECT
276
+ (SELECT id FROM date_dimension d WHERE d.month_epoch = date_dimension.month_epoch ORDER BY d.date_id LIMIT 1),
277
+ visits_daily_fact_y2014m08.tenant_dimension_id,
278
+ visits_daily_fact_y2014m08.user_dimension_id,
279
+ visits_daily_fact_y2014m08.user_agent_type_id,
280
+ visits_daily_fact_y2014m08.feature_type_id,
281
+ SUM(visits_daily_fact_y2014m08.total),
282
+ (SELECT month_epoch FROM date_dimension d WHERE d.month_epoch = date_dimension.month_epoch ORDER BY d.date_id LIMIT 1)
283
+ FROM
284
+ visits_daily_fact_y2014m08
285
+ JOIN
286
+ date_dimension
287
+ ON
288
+ date_dimension.id = visits_daily_fact_y2014m08.date_dimension_id
289
+ GROUP BY
290
+ date_dimension.month_epoch,
291
+ visits_daily_fact_y2014m08.tenant_dimension_id,
292
+ visits_daily_fact_y2014m08.user_dimension_id,
293
+ visits_daily_fact_y2014m08.user_agent_type_id,
294
+ visits_daily_fact_y2014m08.feature_type_id
295
+ ;
296
+
297
+ CREATE INDEX visits_monthly_fact_y2014m08_stage_cluster_type_id_index ON visits_monthly_fact_y2014m08_stage (cluster_type_id);
298
+ CREATE INDEX visits_monthly_fact_y2014m08_stage_date_dimension_id_index ON visits_monthly_fact_y2014m08_stage (date_dimension_id);
299
+ CREATE INDEX visits_monthly_fact_y2014m08_stage_tenant_dimension_id_index ON visits_monthly_fact_y2014m08_stage (tenant_dimension_id);
300
+ CREATE INDEX visits_monthly_fact_y2014m08_stage_user_dimension_id_index ON visits_monthly_fact_y2014m08_stage (user_dimension_id);
301
+ CREATE INDEX visits_monthly_fact_y2014m08_stage_user_agent_type_id_index ON visits_monthly_fact_y2014m08_stage (user_agent_type_id);
302
+ CREATE INDEX visits_monthly_fact_y2014m08_stage_feature_type_id_index ON visits_monthly_fact_y2014m08_stage (feature_type_id);
303
+ CREATE INDEX visits_monthly_fact_y2014m08_stage_time_key_index ON visits_monthly_fact_y2014m08_stage (time_key);
304
+
305
+ COMMIT;
306
+
307
+ BEGIN;
308
+
309
+ DROP TABLE IF EXISTS visits_monthly_fact_y2014m08;
310
+ ALTER TABLE visits_monthly_fact_y2014m08_stage RENAME TO visits_monthly_fact_y2014m08;
311
+
312
+ ALTER TABLE visits_monthly_fact_y2014m08 INHERIT visits_monthly_fact;
313
+ ALTER TABLE visits_monthly_fact_y2014m08 ADD CONSTRAINT visits_monthly_fact_y2014m08_time_key_check CHECK (time_key >= 1406851200 AND time_key < 1409529600) NOT VALID;
314
+ ALTER TABLE visits_monthly_fact_y2014m08 ADD CONSTRAINT visits_monthly_fact_y2014m08_cluster_type_id_fkey FOREIGN KEY (cluster_type_id) REFERENCES cluster_type(id) NOT VALID;
315
+ ALTER TABLE visits_monthly_fact_y2014m08 ADD CONSTRAINT visits_monthly_fact_y2014m08_date_dimension_id_fkey FOREIGN KEY (date_dimension_id) REFERENCES date_dimension(id) NOT VALID;
316
+ ALTER TABLE visits_monthly_fact_y2014m08 ADD CONSTRAINT visits_monthly_fact_y2014m08_tenant_dimension_id_fkey FOREIGN KEY (tenant_dimension_id) REFERENCES tenant_dimension(id) NOT VALID;
317
+ ALTER TABLE visits_monthly_fact_y2014m08 ADD CONSTRAINT visits_monthly_fact_y2014m08_user_dimension_id_fkey FOREIGN KEY (user_dimension_id) REFERENCES user_dimension(id) NOT VALID;
318
+ ALTER TABLE visits_monthly_fact_y2014m08 ADD CONSTRAINT visits_monthly_fact_y2014m08_user_agent_type_id_fkey FOREIGN KEY (user_agent_type_id) REFERENCES user_agent_type(id) NOT VALID;
319
+ ALTER TABLE visits_monthly_fact_y2014m08 ADD CONSTRAINT visits_monthly_fact_y2014m08_feature_type_id_fkey FOREIGN KEY (feature_type_id) REFERENCES feature_type(id) NOT VALID;
320
+
321
+ ALTER INDEX visits_monthly_fact_y2014m08_stage_cluster_type_id_index RENAME TO visits_monthly_fact_y2014m08_cluster_type_id_index;
322
+ ALTER INDEX visits_monthly_fact_y2014m08_stage_date_dimension_id_index RENAME TO visits_monthly_fact_y2014m08_date_dimension_id_index;
323
+ ALTER INDEX visits_monthly_fact_y2014m08_stage_tenant_dimension_id_index RENAME TO visits_monthly_fact_y2014m08_tenant_dimension_id_index;
324
+ ALTER INDEX visits_monthly_fact_y2014m08_stage_user_dimension_id_index RENAME TO visits_monthly_fact_y2014m08_user_dimension_id_index;
325
+ ALTER INDEX visits_monthly_fact_y2014m08_stage_user_agent_type_id_index RENAME TO visits_monthly_fact_y2014m08_user_agent_type_id_index;
326
+ ALTER INDEX visits_monthly_fact_y2014m08_stage_feature_type_id_index RENAME TO visits_monthly_fact_y2014m08_feature_type_id_index;
327
+ ALTER INDEX visits_monthly_fact_y2014m08_stage_time_key_index RENAME TO visits_monthly_fact_y2014m08_time_key_index;
328
+
329
+ COMMIT;
330
+ EOS
331
+ end
332
+ end
333
+ end
@@ -0,0 +1,103 @@
1
+ # The MIT License (MIT)
2
+ #
3
+ # Copyright (c) 2014-2015, VMware, Inc. All Rights Reserved.
4
+ #
5
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ # of this software and associated documentation files (the "Software"), to deal
7
+ # in the Software without restriction, including without limitation the rights
8
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ # copies of the Software, and to permit persons to whom the Software is
10
+ # furnished to do so, subject to the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be included in
13
+ # all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ # THE SOFTWARE.
22
+
23
+ require 'spec_helper'
24
+
25
+ describe Masamune::Transform::SnapshotDimension do
26
+ before do
27
+ catalog.schema :postgres do
28
+ dimension 'user_account_state', type: :mini do
29
+ column 'name', type: :string, unique: true
30
+ column 'description', type: :string
31
+ end
32
+
33
+ dimension 'user', type: :four do
34
+ references :user_account_state
35
+ column 'tenant_id', index: true, natural_key: true
36
+ column 'user_id', index: true, natural_key: true
37
+ column 'preferences', type: :key_value, null: true
38
+ end
39
+ end
40
+ end
41
+
42
+ let(:target) { catalog.postgres.user_dimension }
43
+
44
+ context 'with postgres dimension' do
45
+ subject(:result) { transform.snapshot_dimension(target.ledger_table, target.stage_table).to_s }
46
+
47
+ it 'should eq render snapshot_dimension template' do
48
+ is_expected.to eq <<-EOS.strip_heredoc
49
+ WITH ranges AS (
50
+ SELECT *,
51
+ CASE WHEN delta = 0
52
+ THEN 1 ELSE NULL END r
53
+ FROM user_dimension_ledger
54
+ ), windows AS (
55
+ SELECT *,
56
+ SUM(r) OVER (ORDER BY tenant_id, user_id, start_at DESC, delta, source_uuid) window_id
57
+ FROM ranges
58
+ ), snapshot AS (
59
+ SELECT
60
+ consolidated.user_account_state_type_id,
61
+ consolidated.tenant_id,
62
+ consolidated.user_id,
63
+ consolidated.preferences,
64
+ consolidated.parent_id,
65
+ consolidated.record_id,
66
+ consolidated.start_at
67
+ FROM (
68
+ SELECT DISTINCT ON (tenant_id, user_id, start_at)
69
+ FIRST_VALUE(id) OVER w AS parent_id,
70
+ FIRST_VALUE(start_at) OVER w AS parent_start_at,
71
+ id AS record_id,
72
+ coalesce_merge(user_account_state_type_id) OVER w AS user_account_state_type_id,
73
+ tenant_id AS tenant_id,
74
+ user_id AS user_id,
75
+ hstore_merge(preferences_now) OVER w - hstore_merge(preferences_was) OVER w AS preferences,
76
+ start_at AS start_at
77
+ FROM
78
+ windows
79
+ WINDOW w AS (PARTITION BY tenant_id, user_id, window_id ORDER BY start_at DESC)
80
+ ORDER BY tenant_id, user_id, start_at DESC, window_id
81
+ ) consolidated
82
+ WHERE
83
+ consolidated.user_account_state_type_id IS NOT NULL AND
84
+ consolidated.tenant_id IS NOT NULL AND
85
+ consolidated.user_id IS NOT NULL
86
+ )
87
+ INSERT INTO
88
+ user_dimension_stage (user_account_state_type_id, tenant_id, user_id, preferences, parent_id, record_id, start_at)
89
+ SELECT
90
+ user_account_state_type_id,
91
+ tenant_id,
92
+ user_id,
93
+ preferences,
94
+ parent_id,
95
+ record_id,
96
+ start_at
97
+ FROM
98
+ snapshot
99
+ ;
100
+ EOS
101
+ end
102
+ end
103
+ end
@@ -0,0 +1,115 @@
1
+ # The MIT License (MIT)
2
+ #
3
+ # Copyright (c) 2014-2015, VMware, Inc. All Rights Reserved.
4
+ #
5
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ # of this software and associated documentation files (the "Software"), to deal
7
+ # in the Software without restriction, including without limitation the rights
8
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ # copies of the Software, and to permit persons to whom the Software is
10
+ # furnished to do so, subject to the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be included in
13
+ # all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ # THE SOFTWARE.
22
+
23
+ require 'spec_helper'
24
+
25
+ describe Masamune::Transform::StageDimension do
26
+ before do
27
+ catalog.schema :postgres do
28
+ dimension 'cluster', type: :mini do
29
+ column 'id', type: :integer, surrogate_key: true, auto: true
30
+ column 'name', type: :string, unique: true
31
+ row name: 'default', attributes: {default: true}
32
+ end
33
+
34
+ dimension 'user_account_state', type: :mini do
35
+ column 'name', type: :string, unique: true
36
+ column 'description', type: :string
37
+ row name: 'registered', description: 'Registered'
38
+ row name: 'active', description: 'Active', attributes: {default: true}
39
+ row name: 'inactive', description: 'Inactive'
40
+ end
41
+
42
+ dimension 'department', type: :mini do
43
+ references :cluster
44
+ column 'tenant_id', type: :integer, unique: true, natural_key: true
45
+ column 'department_id', type: :integer, unique: true, natural_key: true
46
+ row tenant_id: -1, department_id: -1, attributes: {default: true}
47
+ end
48
+
49
+ dimension 'user', type: :four do
50
+ references :cluster
51
+ references :department, insert: true
52
+ references :user_account_state
53
+ references :user_account_state, label: :hr
54
+ column 'tenant_id', index: true, natural_key: true
55
+ column 'user_id', index: true, natural_key: true
56
+ column 'name', type: :string
57
+ column 'preferences', type: :key_value, null: true
58
+ end
59
+
60
+ file 'user' do
61
+ column 'tenant_id', type: :integer
62
+ column 'user_id', type: :integer
63
+ column 'department.department_id', type: :integer
64
+ column 'user_account_state.name', type: :string
65
+ column 'hr_user_account_state.name', type: :string
66
+ column 'preferences_now', type: :json
67
+ column 'start_at', type: :timestamp
68
+ column 'source_kind', type: :string
69
+ column 'delta', type: :integer
70
+ end
71
+ end
72
+ end
73
+
74
+ let(:target) { catalog.postgres.user_dimension.ledger_table }
75
+ let(:source) { catalog.postgres.user_file.stage_table(suffix: 'file', table: target, inherit: false) }
76
+
77
+ context 'for postgres dimension' do
78
+ subject(:result) { transform.stage_dimension(source, target).to_s }
79
+
80
+ it 'should eq render stage_dimension template' do
81
+ is_expected.to eq <<-EOS.strip_heredoc
82
+ CREATE TEMPORARY TABLE IF NOT EXISTS user_dimension_ledger_stage (LIKE user_dimension_ledger INCLUDING ALL);
83
+
84
+ INSERT INTO
85
+ user_dimension_ledger_stage (department_type_id, user_account_state_type_id, hr_user_account_state_type_id, tenant_id, user_id, preferences_now, source_kind, start_at, delta)
86
+ SELECT
87
+ department_type.id,
88
+ user_account_state_type.id,
89
+ hr_user_account_state_type.id,
90
+ user_file_dimension_ledger_stage.tenant_id,
91
+ user_file_dimension_ledger_stage.user_id,
92
+ json_to_hstore(user_file_dimension_ledger_stage.preferences_now),
93
+ user_file_dimension_ledger_stage.source_kind,
94
+ user_file_dimension_ledger_stage.start_at,
95
+ user_file_dimension_ledger_stage.delta
96
+ FROM
97
+ user_file_dimension_ledger_stage
98
+ LEFT JOIN
99
+ department_type AS department_type
100
+ ON
101
+ department_type.department_id = user_file_dimension_ledger_stage.department_type_department_id AND
102
+ department_type.tenant_id = user_file_dimension_ledger_stage.tenant_id
103
+ LEFT JOIN
104
+ user_account_state_type AS user_account_state_type
105
+ ON
106
+ user_account_state_type.name = user_file_dimension_ledger_stage.user_account_state_type_name
107
+ LEFT JOIN
108
+ user_account_state_type AS hr_user_account_state_type
109
+ ON
110
+ hr_user_account_state_type.name = user_file_dimension_ledger_stage.hr_user_account_state_type_name
111
+ ;
112
+ EOS
113
+ end
114
+ end
115
+ end