masamune 0.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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