masamune 0.12.3 → 0.13.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (33) hide show
  1. checksums.yaml +4 -4
  2. data/bin/masamune-dump +4 -0
  3. data/lib/masamune/schema/column.rb +2 -20
  4. data/lib/masamune/schema/dimension.rb +12 -11
  5. data/lib/masamune/schema/fact.rb +10 -1
  6. data/lib/masamune/schema/map.rb +3 -3
  7. data/lib/masamune/schema/row.rb +1 -1
  8. data/lib/masamune/schema/table.rb +55 -23
  9. data/lib/masamune/schema/table_reference.rb +5 -0
  10. data/lib/masamune/tasks/dump_thor.rb +58 -0
  11. data/lib/masamune/tasks/shell_thor.rb +0 -19
  12. data/lib/masamune/template.rb +1 -2
  13. data/lib/masamune/transform/define_foreign_key.psql.erb +39 -0
  14. data/lib/masamune/transform/define_index.psql.erb +7 -3
  15. data/lib/masamune/transform/define_schema.rb +3 -3
  16. data/lib/masamune/transform/define_table.psql.erb +24 -3
  17. data/lib/masamune/transform/define_table.rb +16 -2
  18. data/lib/masamune/transform/define_unique.psql.erb +1 -1
  19. data/lib/masamune/transform/denormalize_table.rb +5 -1
  20. data/lib/masamune/transform/replace_table.psql.erb +9 -13
  21. data/lib/masamune/transform/stage_fact.rb +16 -10
  22. data/lib/masamune/version.rb +1 -1
  23. data/spec/masamune/schema/map_spec.rb +1 -1
  24. data/spec/masamune/tasks/dump_thor_spec.rb +42 -0
  25. data/spec/masamune/tasks/shell_thor_spec.rb +0 -11
  26. data/spec/masamune/template_spec.rb +5 -0
  27. data/spec/masamune/transform/define_table.dimension_spec.rb +81 -52
  28. data/spec/masamune/transform/define_table.fact_spec.rb +27 -63
  29. data/spec/masamune/transform/define_table.table_spec.rb +397 -32
  30. data/spec/masamune/transform/denormalize_table_spec.rb +20 -0
  31. data/spec/masamune/transform/rollup_fact_spec.rb +54 -54
  32. data/spec/masamune/transform/stage_fact_spec.rb +57 -34
  33. metadata +9 -3
@@ -33,10 +33,12 @@ describe Masamune::Transform::DefineTable do
33
33
  end
34
34
 
35
35
  dimension 'date', type: :date do
36
- column 'date_id', type: :integer, unique: true, index: true, natural_key: true
36
+ column 'date_id', type: :integer, natural_key: true
37
37
  end
38
38
 
39
39
  dimension 'user_agent', type: :mini do
40
+ references :cluster
41
+
40
42
  column 'name', type: :string, unique: true, index: 'shared'
41
43
  column 'version', type: :string, unique: true, index: 'shared', default: 'Unknown'
42
44
  column 'description', type: :string, null: true, ignore: true
@@ -47,15 +49,21 @@ describe Masamune::Transform::DefineTable do
47
49
  end
48
50
 
49
51
  dimension 'tenant', type: :two do
50
- column 'tenant_id', type: :integer, index: true, natural_key: true
52
+ references :cluster
53
+
54
+ column 'tenant_id', type: :integer, natural_key: true
51
55
  end
52
56
 
53
57
  dimension 'user', type: :two do
54
- column 'tenant_id', type: :integer, index: true, natural_key: true
55
- column 'user_id', type: :integer, index: true, natural_key: true
58
+ references :cluster
59
+
60
+ column 'tenant_id', type: :integer, natural_key: true
61
+ column 'user_id', type: :integer, natural_key: true
56
62
  end
57
63
 
58
64
  dimension 'group', type: :two do
65
+ references :cluster
66
+
59
67
  column 'group_id', type: :integer, natural_key: true
60
68
  end
61
69
 
@@ -125,57 +133,17 @@ describe Masamune::Transform::DefineTable do
125
133
  is_expected.to eq <<-EOS.strip_heredoc
126
134
  CREATE TABLE IF NOT EXISTS visits_fact
127
135
  (
128
- cluster_type_id INTEGER NOT NULL REFERENCES cluster_type(id) DEFAULT default_cluster_type_id(),
129
- date_dimension_id INTEGER NOT NULL REFERENCES date_dimension(id),
130
- tenant_dimension_id INTEGER NOT NULL REFERENCES tenant_dimension(id),
131
- user_dimension_id INTEGER NOT NULL REFERENCES user_dimension(id),
136
+ cluster_type_id INTEGER NOT NULL DEFAULT default_cluster_type_id(),
137
+ date_dimension_id INTEGER NOT NULL,
138
+ tenant_dimension_id INTEGER NOT NULL,
139
+ user_dimension_id INTEGER NOT NULL,
132
140
  group_dimension_id INTEGER[] NOT NULL,
133
- user_agent_type_id INTEGER NOT NULL REFERENCES user_agent_type(id),
134
- feature_type_id INTEGER NOT NULL REFERENCES feature_type(id),
141
+ user_agent_type_id INTEGER NOT NULL,
142
+ feature_type_id INTEGER NOT NULL,
135
143
  total INTEGER NOT NULL,
136
144
  time_key INTEGER NOT NULL,
137
145
  last_modified_at TIMESTAMP NOT NULL DEFAULT NOW()
138
146
  );
139
-
140
- DO $$ BEGIN
141
- IF NOT EXISTS (SELECT 1 FROM pg_class c WHERE c.relname = 'visits_fact_d6b9b38_index') THEN
142
- CREATE INDEX visits_fact_d6b9b38_index ON visits_fact (cluster_type_id);
143
- END IF; END $$;
144
-
145
- DO $$ BEGIN
146
- IF NOT EXISTS (SELECT 1 FROM pg_class c WHERE c.relname = 'visits_fact_0a531a8_index') THEN
147
- CREATE INDEX visits_fact_0a531a8_index ON visits_fact (date_dimension_id);
148
- END IF; END $$;
149
-
150
- DO $$ BEGIN
151
- IF NOT EXISTS (SELECT 1 FROM pg_class c WHERE c.relname = 'visits_fact_d3950d9_index') THEN
152
- CREATE INDEX visits_fact_d3950d9_index ON visits_fact (tenant_dimension_id);
153
- END IF; END $$;
154
-
155
- DO $$ BEGIN
156
- IF NOT EXISTS (SELECT 1 FROM pg_class c WHERE c.relname = 'visits_fact_39f0fdd_index') THEN
157
- CREATE INDEX visits_fact_39f0fdd_index ON visits_fact (user_dimension_id);
158
- END IF; END $$;
159
-
160
- DO $$ BEGIN
161
- IF NOT EXISTS (SELECT 1 FROM pg_class c WHERE c.relname = 'visits_fact_e0d2a9e_index') THEN
162
- CREATE INDEX visits_fact_e0d2a9e_index ON visits_fact (group_dimension_id);
163
- END IF; END $$;
164
-
165
- DO $$ BEGIN
166
- IF NOT EXISTS (SELECT 1 FROM pg_class c WHERE c.relname = 'visits_fact_d8b1c3e_index') THEN
167
- CREATE INDEX visits_fact_d8b1c3e_index ON visits_fact (user_agent_type_id);
168
- END IF; END $$;
169
-
170
- DO $$ BEGIN
171
- IF NOT EXISTS (SELECT 1 FROM pg_class c WHERE c.relname = 'visits_fact_33b68fd_index') THEN
172
- CREATE INDEX visits_fact_33b68fd_index ON visits_fact (feature_type_id);
173
- END IF; END $$;
174
-
175
- DO $$ BEGIN
176
- IF NOT EXISTS (SELECT 1 FROM pg_class c WHERE c.relname = 'visits_fact_6444ed3_index') THEN
177
- CREATE INDEX visits_fact_6444ed3_index ON visits_fact (time_key);
178
- END IF; END $$;
179
147
  EOS
180
148
  end
181
149
  end
@@ -206,12 +174,18 @@ describe Masamune::Transform::DefineTable do
206
174
  COPY visits_file_fact_stage FROM 'output_3.csv' WITH (FORMAT 'csv', HEADER true);
207
175
 
208
176
  CREATE INDEX visits_file_fact_stage_964dac1_index ON visits_file_fact_stage (date_dimension_date_id);
177
+ CREATE INDEX visits_file_fact_stage_5a187ed_index ON visits_file_fact_stage (feature_type_name);
209
178
  CREATE INDEX visits_file_fact_stage_90fc13c_index ON visits_file_fact_stage (tenant_dimension_tenant_id);
210
- CREATE INDEX visits_file_fact_stage_30f3cca_index ON visits_file_fact_stage (user_dimension_user_id);
179
+ CREATE INDEX visits_file_fact_stage_6444ed3_index ON visits_file_fact_stage (time_key);
211
180
  CREATE INDEX visits_file_fact_stage_99c433b_index ON visits_file_fact_stage (user_agent_type_name);
212
181
  CREATE INDEX visits_file_fact_stage_d5d236f_index ON visits_file_fact_stage (user_agent_type_version);
213
- CREATE INDEX visits_file_fact_stage_5a187ed_index ON visits_file_fact_stage (feature_type_name);
214
- CREATE INDEX visits_file_fact_stage_6444ed3_index ON visits_file_fact_stage (time_key);
182
+ CREATE INDEX visits_file_fact_stage_30f3cca_index ON visits_file_fact_stage (user_dimension_user_id);
183
+ CREATE INDEX visits_file_fact_stage_8608ecc_index ON visits_file_fact_stage (date_dimension_date_id, time_key);
184
+ CREATE INDEX visits_file_fact_stage_28291db_index ON visits_file_fact_stage (feature_type_name, time_key);
185
+ CREATE INDEX visits_file_fact_stage_69e4501_index ON visits_file_fact_stage (tenant_dimension_tenant_id, time_key);
186
+ CREATE INDEX visits_file_fact_stage_766cbfa_index ON visits_file_fact_stage (user_agent_type_name, time_key);
187
+ CREATE INDEX visits_file_fact_stage_0fe2101_index ON visits_file_fact_stage (user_agent_type_version, time_key);
188
+ CREATE INDEX visits_file_fact_stage_b0abfed_index ON visits_file_fact_stage (user_dimension_user_id, time_key);
215
189
 
216
190
  ANALYZE visits_file_fact_stage;
217
191
  EOS
@@ -256,16 +230,6 @@ describe Masamune::Transform::DefineTable do
256
230
  time_key INTEGER NOT NULL,
257
231
  last_modified_at TIMESTAMP NOT NULL DEFAULT NOW()
258
232
  );
259
-
260
- DO $$ BEGIN
261
- IF NOT EXISTS (SELECT 1 FROM pg_class c WHERE c.relname = 'visits_fact_2a6313d_index') THEN
262
- CREATE INDEX visits_fact_2a6313d_index ON visits_fact (message_kind_type_id);
263
- END IF; END $$;
264
-
265
- DO $$ BEGIN
266
- IF NOT EXISTS (SELECT 1 FROM pg_class c WHERE c.relname = 'visits_fact_6444ed3_index') THEN
267
- CREATE INDEX visits_fact_6444ed3_index ON visits_fact (time_key);
268
- END IF; END $$;
269
233
  EOS
270
234
  end
271
235
  end
@@ -23,7 +23,10 @@
23
23
  require 'spec_helper'
24
24
 
25
25
  describe Masamune::Transform::DefineTable do
26
- subject { transform.define_table(target).to_s }
26
+ let(:files) { [] }
27
+ let(:options) { {} }
28
+
29
+ subject { transform.define_table(target, files, options).to_s }
27
30
 
28
31
  context 'for postgres table with columns' do
29
32
  before do
@@ -41,10 +44,15 @@ describe Masamune::Transform::DefineTable do
41
44
  is_expected.to eq <<-EOS.strip_heredoc
42
45
  CREATE TABLE IF NOT EXISTS user_table
43
46
  (
44
- id SERIAL PRIMARY KEY,
47
+ id SERIAL,
45
48
  tenant_id INTEGER NOT NULL,
46
49
  user_id INTEGER NOT NULL
47
50
  );
51
+
52
+ DO $$ BEGIN
53
+ IF NOT EXISTS (SELECT 1 FROM pg_class c WHERE c.relname = 'user_table_pkey') THEN
54
+ ALTER TABLE user_table ADD PRIMARY KEY (id);
55
+ END IF; END $$;
48
56
  EOS
49
57
  end
50
58
  end
@@ -65,11 +73,16 @@ describe Masamune::Transform::DefineTable do
65
73
  is_expected.to eq <<-EOS.strip_heredoc
66
74
  CREATE TABLE IF NOT EXISTS user_table
67
75
  (
68
- id SERIAL PRIMARY KEY,
76
+ id SERIAL,
69
77
  tenant_id INTEGER NOT NULL,
70
78
  user_id INTEGER NOT NULL
71
79
  );
72
80
 
81
+ DO $$ BEGIN
82
+ IF NOT EXISTS (SELECT 1 FROM pg_class c WHERE c.relname = 'user_table_pkey') THEN
83
+ ALTER TABLE user_table ADD PRIMARY KEY (id);
84
+ END IF; END $$;
85
+
73
86
  DO $$ BEGIN
74
87
  IF NOT EXISTS (SELECT 1 FROM pg_class c WHERE c.relname = 'user_table_3854361_index') THEN
75
88
  CREATE INDEX user_table_3854361_index ON user_table (tenant_id);
@@ -99,11 +112,16 @@ describe Masamune::Transform::DefineTable do
99
112
  is_expected.to eq <<-EOS.strip_heredoc
100
113
  CREATE TABLE IF NOT EXISTS user_table
101
114
  (
102
- id SERIAL PRIMARY KEY,
115
+ id SERIAL,
103
116
  tenant_id INTEGER NOT NULL,
104
117
  user_id INTEGER NOT NULL
105
118
  );
106
119
 
120
+ DO $$ BEGIN
121
+ IF NOT EXISTS (SELECT 1 FROM pg_class c WHERE c.relname = 'user_table_pkey') THEN
122
+ ALTER TABLE user_table ADD PRIMARY KEY (id);
123
+ END IF; END $$;
124
+
107
125
  DO $$ BEGIN
108
126
  IF NOT EXISTS (SELECT 1 FROM pg_class c WHERE c.relname = 'user_table_3854361_index') THEN
109
127
  CREATE INDEX user_table_3854361_index ON user_table (tenant_id);
@@ -138,11 +156,16 @@ describe Masamune::Transform::DefineTable do
138
156
  is_expected.to eq <<-EOS.strip_heredoc
139
157
  CREATE TABLE IF NOT EXISTS user_table
140
158
  (
141
- id SERIAL PRIMARY KEY,
159
+ id SERIAL,
142
160
  tenant_id INTEGER NOT NULL,
143
161
  user_id INTEGER NOT NULL
144
162
  );
145
163
 
164
+ DO $$ BEGIN
165
+ IF NOT EXISTS (SELECT 1 FROM pg_class c WHERE c.relname = 'user_table_pkey') THEN
166
+ ALTER TABLE user_table ADD PRIMARY KEY (id);
167
+ END IF; END $$;
168
+
146
169
  DO $$ BEGIN
147
170
  IF NOT EXISTS (SELECT 1 FROM pg_class c WHERE c.relname = 'user_table_e8701ad_key') THEN
148
171
  ALTER TABLE user_table ADD CONSTRAINT user_table_e8701ad_key UNIQUE(user_id);
@@ -156,6 +179,201 @@ describe Masamune::Transform::DefineTable do
156
179
  end
157
180
  end
158
181
 
182
+ context 'for postgres table with auto reference' do
183
+ before do
184
+ catalog.schema :postgres do
185
+ table 'cluster' do
186
+ column 'id', surrogate_key: true, auto: true
187
+ end
188
+ table 'user' do
189
+ references :cluster
190
+ column 'tenant_id', natural_key: true
191
+ column 'user_id', natural_key: true
192
+ end
193
+ end
194
+ end
195
+
196
+ let(:target) { catalog.postgres.user_table }
197
+
198
+ it 'should render table template' do
199
+ is_expected.to eq <<-EOS.strip_heredoc
200
+ CREATE TABLE IF NOT EXISTS user_table
201
+ (
202
+ id SERIAL,
203
+ cluster_table_id INTEGER NOT NULL,
204
+ tenant_id INTEGER NOT NULL,
205
+ user_id INTEGER NOT NULL
206
+ );
207
+
208
+ DO $$ BEGIN
209
+ IF NOT EXISTS (SELECT 1 FROM pg_class c WHERE c.relname = 'user_table_pkey') THEN
210
+ ALTER TABLE user_table ADD PRIMARY KEY (cluster_table_id, id);
211
+ END IF; END $$;
212
+
213
+ DO $$ BEGIN
214
+ IF NOT EXISTS (SELECT 1 FROM pg_constraint c WHERE c.conname = 'user_table_8923fdb_fkey') THEN
215
+ ALTER TABLE user_table ADD CONSTRAINT user_table_8923fdb_fkey FOREIGN KEY (cluster_table_id) REFERENCES cluster_table(id);
216
+ END IF; END $$;
217
+
218
+ DO $$ BEGIN
219
+ IF NOT EXISTS (SELECT 1 FROM pg_class c WHERE c.relname = 'user_table_9f1c0d7_key') THEN
220
+ ALTER TABLE user_table ADD CONSTRAINT user_table_9f1c0d7_key UNIQUE(cluster_table_id, tenant_id, user_id);
221
+ END IF; END $$;
222
+
223
+ DO $$ BEGIN
224
+ IF NOT EXISTS (SELECT 1 FROM pg_class c WHERE c.relname = 'user_table_3854361_index') THEN
225
+ CREATE INDEX user_table_3854361_index ON user_table (tenant_id);
226
+ END IF; END $$;
227
+
228
+ DO $$ BEGIN
229
+ IF NOT EXISTS (SELECT 1 FROM pg_class c WHERE c.relname = 'user_table_e8701ad_index') THEN
230
+ CREATE INDEX user_table_e8701ad_index ON user_table (user_id);
231
+ END IF; END $$;
232
+
233
+ DO $$ BEGIN
234
+ IF NOT EXISTS (SELECT 1 FROM pg_class c WHERE c.relname = 'user_table_e0e4295_index') THEN
235
+ CREATE INDEX user_table_e0e4295_index ON user_table (tenant_id, user_id);
236
+ END IF; END $$;
237
+ EOS
238
+ end
239
+ end
240
+
241
+ context 'for postgres table with natural_key auto reference' do
242
+ before do
243
+ catalog.schema :postgres do
244
+ table 'cluster' do
245
+ column 'id', surrogate_key: true, auto: true
246
+ end
247
+ table 'user' do
248
+ references :cluster, natural_key: true
249
+ column 'tenant_id', natural_key: true
250
+ column 'user_id', natural_key: true
251
+ end
252
+ end
253
+ end
254
+
255
+ let(:target) { catalog.postgres.user_table }
256
+
257
+ it 'should render table template' do
258
+ is_expected.to eq <<-EOS.strip_heredoc
259
+ CREATE TABLE IF NOT EXISTS user_table
260
+ (
261
+ id SERIAL,
262
+ cluster_table_id INTEGER NOT NULL,
263
+ tenant_id INTEGER NOT NULL,
264
+ user_id INTEGER NOT NULL
265
+ );
266
+
267
+ DO $$ BEGIN
268
+ IF NOT EXISTS (SELECT 1 FROM pg_class c WHERE c.relname = 'user_table_pkey') THEN
269
+ ALTER TABLE user_table ADD PRIMARY KEY (cluster_table_id, id);
270
+ END IF; END $$;
271
+
272
+ DO $$ BEGIN
273
+ IF NOT EXISTS (SELECT 1 FROM pg_constraint c WHERE c.conname = 'user_table_8923fdb_fkey') THEN
274
+ ALTER TABLE user_table ADD CONSTRAINT user_table_8923fdb_fkey FOREIGN KEY (cluster_table_id) REFERENCES cluster_table(id);
275
+ END IF; END $$;
276
+
277
+ DO $$ BEGIN
278
+ IF NOT EXISTS (SELECT 1 FROM pg_class c WHERE c.relname = 'user_table_9f1c0d7_key') THEN
279
+ ALTER TABLE user_table ADD CONSTRAINT user_table_9f1c0d7_key UNIQUE(cluster_table_id, tenant_id, user_id);
280
+ END IF; END $$;
281
+
282
+ DO $$ BEGIN
283
+ IF NOT EXISTS (SELECT 1 FROM pg_class c WHERE c.relname = 'user_table_8923fdb_index') THEN
284
+ CREATE INDEX user_table_8923fdb_index ON user_table (cluster_table_id);
285
+ END IF; END $$;
286
+
287
+ DO $$ BEGIN
288
+ IF NOT EXISTS (SELECT 1 FROM pg_class c WHERE c.relname = 'user_table_3854361_index') THEN
289
+ CREATE INDEX user_table_3854361_index ON user_table (tenant_id);
290
+ END IF; END $$;
291
+
292
+ DO $$ BEGIN
293
+ IF NOT EXISTS (SELECT 1 FROM pg_class c WHERE c.relname = 'user_table_e8701ad_index') THEN
294
+ CREATE INDEX user_table_e8701ad_index ON user_table (user_id);
295
+ END IF; END $$;
296
+
297
+ DO $$ BEGIN
298
+ IF NOT EXISTS (SELECT 1 FROM pg_class c WHERE c.relname = 'user_table_9f1c0d7_index') THEN
299
+ CREATE UNIQUE INDEX user_table_9f1c0d7_index ON user_table (cluster_table_id, tenant_id, user_id);
300
+ END IF; END $$;
301
+ EOS
302
+ end
303
+ end
304
+
305
+ context 'for postgres table with nested auto reference' do
306
+ before do
307
+ catalog.schema :postgres do
308
+ table 'cluster' do
309
+ column 'id', surrogate_key: true, auto: true
310
+ end
311
+
312
+ table 'department' do
313
+ references :cluster
314
+ column 'department_id', natural_key: true
315
+ end
316
+
317
+ table 'user' do
318
+ references :cluster
319
+ references :department
320
+ column 'tenant_id', natural_key: true
321
+ column 'user_id', natural_key: true
322
+ end
323
+ end
324
+ end
325
+
326
+ let(:target) { catalog.postgres.user_table }
327
+
328
+ it 'should render table template' do
329
+ is_expected.to eq <<-EOS.strip_heredoc
330
+ CREATE TABLE IF NOT EXISTS user_table
331
+ (
332
+ id SERIAL,
333
+ cluster_table_id INTEGER NOT NULL,
334
+ department_table_id INTEGER NOT NULL,
335
+ tenant_id INTEGER NOT NULL,
336
+ user_id INTEGER NOT NULL
337
+ );
338
+
339
+ DO $$ BEGIN
340
+ IF NOT EXISTS (SELECT 1 FROM pg_class c WHERE c.relname = 'user_table_pkey') THEN
341
+ ALTER TABLE user_table ADD PRIMARY KEY (cluster_table_id, id);
342
+ END IF; END $$;
343
+
344
+ DO $$ BEGIN
345
+ IF NOT EXISTS (SELECT 1 FROM pg_constraint c WHERE c.conname = 'user_table_8923fdb_fkey') THEN
346
+ ALTER TABLE user_table ADD CONSTRAINT user_table_8923fdb_fkey FOREIGN KEY (cluster_table_id) REFERENCES cluster_table(id);
347
+ END IF; END $$;
348
+
349
+ DO $$ BEGIN
350
+ IF NOT EXISTS (SELECT 1 FROM pg_constraint c WHERE c.conname = 'user_table_9000538_fkey') THEN
351
+ ALTER TABLE user_table ADD CONSTRAINT user_table_9000538_fkey FOREIGN KEY (cluster_table_id, department_table_id) REFERENCES department_table(cluster_table_id, id);
352
+ END IF; END $$;
353
+
354
+ DO $$ BEGIN
355
+ IF NOT EXISTS (SELECT 1 FROM pg_class c WHERE c.relname = 'user_table_9f1c0d7_key') THEN
356
+ ALTER TABLE user_table ADD CONSTRAINT user_table_9f1c0d7_key UNIQUE(cluster_table_id, tenant_id, user_id);
357
+ END IF; END $$;
358
+
359
+ DO $$ BEGIN
360
+ IF NOT EXISTS (SELECT 1 FROM pg_class c WHERE c.relname = 'user_table_3854361_index') THEN
361
+ CREATE INDEX user_table_3854361_index ON user_table (tenant_id);
362
+ END IF; END $$;
363
+
364
+ DO $$ BEGIN
365
+ IF NOT EXISTS (SELECT 1 FROM pg_class c WHERE c.relname = 'user_table_e8701ad_index') THEN
366
+ CREATE INDEX user_table_e8701ad_index ON user_table (user_id);
367
+ END IF; END $$;
368
+
369
+ DO $$ BEGIN
370
+ IF NOT EXISTS (SELECT 1 FROM pg_class c WHERE c.relname = 'user_table_e0e4295_index') THEN
371
+ CREATE INDEX user_table_e0e4295_index ON user_table (tenant_id, user_id);
372
+ END IF; END $$;
373
+ EOS
374
+ end
375
+ end
376
+
159
377
  context 'for postgres table with enum column' do
160
378
  before do
161
379
  catalog.schema :postgres do
@@ -178,11 +396,16 @@ describe Masamune::Transform::DefineTable do
178
396
 
179
397
  CREATE TABLE IF NOT EXISTS user_table
180
398
  (
181
- id SERIAL PRIMARY KEY,
399
+ id SERIAL,
182
400
  tenant_id INTEGER NOT NULL,
183
401
  user_id INTEGER NOT NULL,
184
402
  state USER_STATE_TYPE NOT NULL DEFAULT 'active'::USER_STATE_TYPE
185
403
  );
404
+
405
+ DO $$ BEGIN
406
+ IF NOT EXISTS (SELECT 1 FROM pg_class c WHERE c.relname = 'user_table_pkey') THEN
407
+ ALTER TABLE user_table ADD PRIMARY KEY (id);
408
+ END IF; END $$;
186
409
  EOS
187
410
  end
188
411
  end
@@ -203,9 +426,14 @@ describe Masamune::Transform::DefineTable do
203
426
  is_expected.to eq <<-EOS.strip_heredoc
204
427
  CREATE TABLE IF NOT EXISTS user_table
205
428
  (
206
- identifier UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
429
+ identifier UUID DEFAULT uuid_generate_v4(),
207
430
  name VARCHAR NOT NULL
208
431
  );
432
+
433
+ DO $$ BEGIN
434
+ IF NOT EXISTS (SELECT 1 FROM pg_class c WHERE c.relname = 'user_table_pkey') THEN
435
+ ALTER TABLE user_table ADD PRIMARY KEY (identifier);
436
+ END IF; END $$;
209
437
  EOS
210
438
  end
211
439
  end
@@ -228,11 +456,16 @@ describe Masamune::Transform::DefineTable do
228
456
  is_expected.to eq <<-EOS.strip_heredoc
229
457
  CREATE TABLE IF NOT EXISTS user_table
230
458
  (
231
- id SERIAL PRIMARY KEY,
459
+ id SERIAL,
232
460
  name VARCHAR NOT NULL,
233
461
  description VARCHAR NOT NULL
234
462
  );
235
463
 
464
+ DO $$ BEGIN
465
+ IF NOT EXISTS (SELECT 1 FROM pg_class c WHERE c.relname = 'user_table_pkey') THEN
466
+ ALTER TABLE user_table ADD PRIMARY KEY (id);
467
+ END IF; END $$;
468
+
236
469
  INSERT INTO user_table (name, description)
237
470
  SELECT 'registered', 'Registered'
238
471
  WHERE NOT EXISTS (SELECT 1 FROM user_table WHERE name = 'registered' AND description = 'Registered');
@@ -262,11 +495,16 @@ describe Masamune::Transform::DefineTable do
262
495
  is_expected.to eq <<-EOS.strip_heredoc
263
496
  CREATE TABLE IF NOT EXISTS user_table
264
497
  (
265
- id SERIAL PRIMARY KEY,
498
+ id SERIAL,
266
499
  tenant_id INTEGER NOT NULL,
267
500
  user_id INTEGER NOT NULL
268
501
  );
269
502
 
503
+ DO $$ BEGIN
504
+ IF NOT EXISTS (SELECT 1 FROM pg_class c WHERE c.relname = 'user_table_pkey') THEN
505
+ ALTER TABLE user_table ADD PRIMARY KEY (id);
506
+ END IF; END $$;
507
+
270
508
  DO $$ BEGIN
271
509
  IF NOT EXISTS (SELECT 1 FROM pg_class c WHERE c.relname = 'user_table_e0e4295_key') THEN
272
510
  ALTER TABLE user_table ADD CONSTRAINT user_table_e0e4295_key UNIQUE(tenant_id, user_id);
@@ -298,16 +536,36 @@ describe Masamune::Transform::DefineTable do
298
536
  is_expected.to eq <<-EOS.strip_heredoc
299
537
  CREATE TABLE IF NOT EXISTS user_table
300
538
  (
301
- id SERIAL PRIMARY KEY,
539
+ id SERIAL,
302
540
  tenant_id INTEGER NOT NULL,
303
541
  user_id INTEGER NOT NULL
304
542
  );
305
543
 
544
+ DO $$ BEGIN
545
+ IF NOT EXISTS (SELECT 1 FROM pg_class c WHERE c.relname = 'user_table_pkey') THEN
546
+ ALTER TABLE user_table ADD PRIMARY KEY (id);
547
+ END IF; END $$;
548
+
306
549
  DO $$ BEGIN
307
550
  IF NOT EXISTS (SELECT 1 FROM pg_class c WHERE c.relname = 'user_table_e0e4295_key') THEN
308
551
  ALTER TABLE user_table ADD CONSTRAINT user_table_e0e4295_key UNIQUE(tenant_id, user_id);
309
552
  END IF; END $$;
310
553
 
554
+ DO $$ BEGIN
555
+ IF NOT EXISTS (SELECT 1 FROM pg_class c WHERE c.relname = 'user_table_3854361_index') THEN
556
+ CREATE INDEX user_table_3854361_index ON user_table (tenant_id);
557
+ END IF; END $$;
558
+
559
+ DO $$ BEGIN
560
+ IF NOT EXISTS (SELECT 1 FROM pg_class c WHERE c.relname = 'user_table_e8701ad_index') THEN
561
+ CREATE INDEX user_table_e8701ad_index ON user_table (user_id);
562
+ END IF; END $$;
563
+
564
+ DO $$ BEGIN
565
+ IF NOT EXISTS (SELECT 1 FROM pg_class c WHERE c.relname = 'user_table_e0e4295_index') THEN
566
+ CREATE UNIQUE INDEX user_table_e0e4295_index ON user_table (tenant_id, user_id);
567
+ END IF; END $$;
568
+
311
569
  INSERT INTO user_table (tenant_id, user_id)
312
570
  SELECT default_tenant_id(), -1
313
571
  WHERE NOT EXISTS (SELECT 1 FROM user_table WHERE tenant_id = default_tenant_id() AND user_id = -1);
@@ -318,9 +576,9 @@ describe Masamune::Transform::DefineTable do
318
576
 
319
577
  ANALYZE user_table;
320
578
 
321
- CREATE OR REPLACE FUNCTION default_user_id()
579
+ CREATE OR REPLACE FUNCTION default_user_table_user_id()
322
580
  RETURNS INTEGER IMMUTABLE AS $$
323
- SELECT -1;
581
+ SELECT CAST(-1 AS INTEGER);
324
582
  $$ LANGUAGE SQL;
325
583
 
326
584
  CREATE OR REPLACE FUNCTION default_user_table_id()
@@ -328,9 +586,9 @@ describe Masamune::Transform::DefineTable do
328
586
  SELECT id FROM user_table WHERE tenant_id = default_tenant_id() AND user_id = -1;
329
587
  $$ LANGUAGE SQL;
330
588
 
331
- CREATE OR REPLACE FUNCTION unknown_user_id()
589
+ CREATE OR REPLACE FUNCTION unknown_user_table_user_id()
332
590
  RETURNS INTEGER IMMUTABLE AS $$
333
- SELECT -2;
591
+ SELECT CAST(-2 AS INTEGER);
334
592
  $$ LANGUAGE SQL;
335
593
 
336
594
  CREATE OR REPLACE FUNCTION unknown_user_table_id()
@@ -365,14 +623,19 @@ describe Masamune::Transform::DefineTable do
365
623
  is_expected.to eq <<-EOS.strip_heredoc
366
624
  CREATE TABLE IF NOT EXISTS user_table
367
625
  (
368
- id SERIAL PRIMARY KEY,
369
- user_account_state_table_id INTEGER NOT NULL REFERENCES user_account_state_table(id) DEFAULT default_user_account_state_table_id(),
626
+ id SERIAL,
627
+ user_account_state_table_id INTEGER NOT NULL DEFAULT default_user_account_state_table_id(),
370
628
  name VARCHAR NOT NULL
371
629
  );
372
630
 
373
631
  DO $$ BEGIN
374
- IF NOT EXISTS (SELECT 1 FROM pg_class c WHERE c.relname = 'user_table_bd2027e_index') THEN
375
- CREATE INDEX user_table_bd2027e_index ON user_table (user_account_state_table_id);
632
+ IF NOT EXISTS (SELECT 1 FROM pg_class c WHERE c.relname = 'user_table_pkey') THEN
633
+ ALTER TABLE user_table ADD PRIMARY KEY (id);
634
+ END IF; END $$;
635
+
636
+ DO $$ BEGIN
637
+ IF NOT EXISTS (SELECT 1 FROM pg_constraint c WHERE c.conname = 'user_table_bd2027e_fkey') THEN
638
+ ALTER TABLE user_table ADD CONSTRAINT user_table_bd2027e_fkey FOREIGN KEY (user_account_state_table_id) REFERENCES user_account_state_table(id);
376
639
  END IF; END $$;
377
640
  EOS
378
641
  end
@@ -401,20 +664,25 @@ describe Masamune::Transform::DefineTable do
401
664
  is_expected.to eq <<-EOS.strip_heredoc
402
665
  CREATE TABLE IF NOT EXISTS user_table
403
666
  (
404
- id SERIAL PRIMARY KEY,
405
- user_account_state_table_id INTEGER NOT NULL REFERENCES user_account_state_table(id) DEFAULT default_user_account_state_table_id(),
406
- hr_user_account_state_table_id INTEGER REFERENCES user_account_state_table(id),
667
+ id SERIAL,
668
+ user_account_state_table_id INTEGER NOT NULL DEFAULT default_user_account_state_table_id(),
669
+ hr_user_account_state_table_id INTEGER,
407
670
  name VARCHAR NOT NULL
408
671
  );
409
672
 
410
673
  DO $$ BEGIN
411
- IF NOT EXISTS (SELECT 1 FROM pg_class c WHERE c.relname = 'user_table_bd2027e_index') THEN
412
- CREATE INDEX user_table_bd2027e_index ON user_table (user_account_state_table_id);
674
+ IF NOT EXISTS (SELECT 1 FROM pg_class c WHERE c.relname = 'user_table_pkey') THEN
675
+ ALTER TABLE user_table ADD PRIMARY KEY (id);
676
+ END IF; END $$;
677
+
678
+ DO $$ BEGIN
679
+ IF NOT EXISTS (SELECT 1 FROM pg_constraint c WHERE c.conname = 'user_table_bd2027e_fkey') THEN
680
+ ALTER TABLE user_table ADD CONSTRAINT user_table_bd2027e_fkey FOREIGN KEY (user_account_state_table_id) REFERENCES user_account_state_table(id);
413
681
  END IF; END $$;
414
682
 
415
683
  DO $$ BEGIN
416
- IF NOT EXISTS (SELECT 1 FROM pg_class c WHERE c.relname = 'user_table_074da4a_index') THEN
417
- CREATE INDEX user_table_074da4a_index ON user_table (hr_user_account_state_table_id);
684
+ IF NOT EXISTS (SELECT 1 FROM pg_constraint c WHERE c.conname = 'user_table_074da4a_fkey') THEN
685
+ ALTER TABLE user_table ADD CONSTRAINT user_table_074da4a_fkey FOREIGN KEY (hr_user_account_state_table_id) REFERENCES user_account_state_table(id);
418
686
  END IF; END $$;
419
687
  EOS
420
688
  end
@@ -450,9 +718,6 @@ describe Masamune::Transform::DefineTable do
450
718
  hr_user_account_state_table_id INTEGER,
451
719
  name VARCHAR
452
720
  );
453
-
454
- CREATE INDEX user_table_stage_bd2027e_index ON user_table_stage (user_account_state_table_id);
455
- CREATE INDEX user_table_stage_074da4a_index ON user_table_stage (hr_user_account_state_table_id);
456
721
  EOS
457
722
  end
458
723
  end
@@ -468,9 +733,6 @@ describe Masamune::Transform::DefineTable do
468
733
  user_account_state_table_id INTEGER,
469
734
  name VARCHAR
470
735
  );
471
-
472
- CREATE INDEX user_table_stage_074da4a_index ON user_table_stage (hr_user_account_state_table_id);
473
- CREATE INDEX user_table_stage_bd2027e_index ON user_table_stage (user_account_state_table_id);
474
736
  EOS
475
737
  end
476
738
  end
@@ -514,11 +776,16 @@ describe Masamune::Transform::DefineTable do
514
776
 
515
777
  CREATE TABLE IF NOT EXISTS user_table
516
778
  (
517
- id INTEGER PRIMARY KEY DEFAULT nextval('user_table_id_seq'),
779
+ id INTEGER DEFAULT nextval('user_table_id_seq'),
518
780
  tenant_id INTEGER NOT NULL,
519
781
  user_id INTEGER NOT NULL
520
782
  );
521
783
 
784
+ DO $$ BEGIN
785
+ IF NOT EXISTS (SELECT 1 FROM pg_class c WHERE c.relname = 'user_table_pkey') THEN
786
+ ALTER TABLE user_table ADD PRIMARY KEY (id);
787
+ END IF; END $$;
788
+
522
789
  DO $$ BEGIN
523
790
  IF NOT EXISTS (SELECT 1 WHERE sequence_owner('user_table_id_seq') = 'user_table.id') THEN
524
791
  ALTER SEQUENCE user_table_id_seq OWNED BY user_table.id;
@@ -526,4 +793,102 @@ describe Masamune::Transform::DefineTable do
526
793
  EOS
527
794
  end
528
795
  end
796
+
797
+ context 'for postgres table with index columns and with_index: false' do
798
+ before do
799
+ catalog.schema :postgres do
800
+ table 'user' do
801
+ column 'tenant_id', index: true
802
+ column 'user_id', index: true
803
+ end
804
+ end
805
+ end
806
+
807
+ let(:options) { { with_index: false } }
808
+ let(:target) { catalog.postgres.user_table }
809
+
810
+ it 'should render table template' do
811
+ is_expected.to eq <<-EOS.strip_heredoc
812
+ CREATE TABLE IF NOT EXISTS user_table
813
+ (
814
+ id SERIAL,
815
+ tenant_id INTEGER NOT NULL,
816
+ user_id INTEGER NOT NULL
817
+ );
818
+
819
+ DO $$ BEGIN
820
+ IF NOT EXISTS (SELECT 1 FROM pg_class c WHERE c.relname = 'user_table_pkey') THEN
821
+ ALTER TABLE user_table ADD PRIMARY KEY (id);
822
+ END IF; END $$;
823
+ EOS
824
+ end
825
+ end
826
+
827
+ context 'for postgres table with referenced tables and with_foreign_key: false' do
828
+ before do
829
+ catalog.schema :postgres do
830
+ table 'user_account_state' do
831
+ column 'name', type: :string, unique: true
832
+ column 'description', type: :string
833
+ row name: 'registered', description: 'Registered'
834
+ row name: 'active', description: 'Active', attributes: { default: true }
835
+ row name: 'inactive', description: 'Inactive'
836
+ end
837
+
838
+ table 'user' do
839
+ references :user_account_state
840
+ column 'name', type: :string
841
+ end
842
+ end
843
+ end
844
+
845
+ let(:options) { { with_foreign_key: false } }
846
+ let(:target) { catalog.postgres.user_table }
847
+
848
+ it 'should render table template' do
849
+ is_expected.to eq <<-EOS.strip_heredoc
850
+ CREATE TABLE IF NOT EXISTS user_table
851
+ (
852
+ id SERIAL,
853
+ user_account_state_table_id INTEGER NOT NULL DEFAULT default_user_account_state_table_id(),
854
+ name VARCHAR NOT NULL
855
+ );
856
+
857
+ DO $$ BEGIN
858
+ IF NOT EXISTS (SELECT 1 FROM pg_class c WHERE c.relname = 'user_table_pkey') THEN
859
+ ALTER TABLE user_table ADD PRIMARY KEY (id);
860
+ END IF; END $$;
861
+ EOS
862
+ end
863
+ end
864
+
865
+ context 'for postgres table with unique columns and with_unique_constraint: false' do
866
+ before do
867
+ catalog.schema :postgres do
868
+ table 'user' do
869
+ column 'tenant_id', unique: true
870
+ column 'user_id'
871
+ end
872
+ end
873
+ end
874
+
875
+ let(:options) { { with_unique_constraint: false } }
876
+ let(:target) { catalog.postgres.user_table }
877
+
878
+ it 'should render table template' do
879
+ is_expected.to eq <<-EOS.strip_heredoc
880
+ CREATE TABLE IF NOT EXISTS user_table
881
+ (
882
+ id SERIAL,
883
+ tenant_id INTEGER NOT NULL,
884
+ user_id INTEGER NOT NULL
885
+ );
886
+
887
+ DO $$ BEGIN
888
+ IF NOT EXISTS (SELECT 1 FROM pg_class c WHERE c.relname = 'user_table_pkey') THEN
889
+ ALTER TABLE user_table ADD PRIMARY KEY (id);
890
+ END IF; END $$;
891
+ EOS
892
+ end
893
+ end
529
894
  end