masamune 0.13.0 → 0.13.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/masamune/actions/date_parse.rb +1 -1
- data/lib/masamune/commands/postgres_admin.rb +19 -3
- data/lib/masamune/data_plan/rule.rb +14 -5
- data/lib/masamune/schema/fact.rb +14 -3
- data/lib/masamune/schema/table.rb +7 -2
- data/lib/masamune/tasks/dump_thor.rb +12 -5
- data/lib/masamune/template.rb +1 -1
- data/lib/masamune/transform/define_inheritance.psql.erb +28 -0
- data/lib/masamune/transform/define_schema.rb +5 -2
- data/lib/masamune/transform/define_table.psql.erb +23 -8
- data/lib/masamune/transform/define_table.rb +95 -4
- data/lib/masamune/transform/denormalize_table.rb +3 -0
- data/lib/masamune/transform/operator.rb +10 -1
- data/lib/masamune/transform/replace_table.psql.erb +2 -6
- data/lib/masamune/version.rb +1 -1
- data/spec/masamune/commands/postgres_admin_spec.rb +16 -1
- data/spec/masamune/data_plan/engine_spec.rb +2 -2
- data/spec/masamune/data_plan/rule_spec.rb +25 -10
- data/spec/masamune/schema/fact_spec.rb +84 -44
- data/spec/masamune/tasks/dump_thor_spec.rb +46 -6
- data/spec/masamune/thor_spec.rb +12 -27
- data/spec/masamune/transform/define_schema_spec.rb +30 -6
- data/spec/masamune/transform/define_table.fact_spec.rb +11 -0
- data/spec/masamune/transform/define_table.table_spec.rb +106 -18
- data/spec/masamune/transform/denormalize_table_spec.rb +71 -2
- data/spec/masamune/transform/rollup_fact_spec.rb +3 -0
- data/spec/masamune/transform/stage_fact_spec.rb +1 -0
- data/spec/support/rspec/example/task_example_group.rb +17 -0
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 49fdc180c59d4179763efd965d946c93fb864dcf
|
4
|
+
data.tar.gz: 0765d61a7a7247c7bb5eb0d70d17c7edb5e5fcf5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7a121d38a8d42a7e0c255ba17e523e1520da7016e0a87d553adcd32c67f6af21eb2ffc81cbcda1123e286fd93cdde8b31177affa30e17314497248d820fea989
|
7
|
+
data.tar.gz: 93ab83f1f5804d0b3bf25970a665d63f3e7099c43ec6c817e8a04ee30ad3dde348aa4a2515a1a8518e76aeb0150eed04a77cf1a568710f806dbe4582f1502259
|
@@ -30,7 +30,7 @@ module Masamune::Actions
|
|
30
30
|
def parse_datetime_type(key)
|
31
31
|
value = options[key]
|
32
32
|
Chronic.parse(value).tap do |datetime_value|
|
33
|
-
|
33
|
+
logger.debug("Using '#{datetime_value}' for --#{key}") if value != datetime_value
|
34
34
|
end or raise Thor::MalformattedArgumentError, "Expected date time value for '--#{key}'; got #{value}"
|
35
35
|
end
|
36
36
|
|
@@ -30,12 +30,14 @@ module Masamune::Commands
|
|
30
30
|
{
|
31
31
|
:create_db_path => 'createdb',
|
32
32
|
:drop_db_path => 'dropdb',
|
33
|
+
:pg_dump_path => 'pg_dump',
|
33
34
|
:options => [],
|
34
35
|
:hostname => 'localhost',
|
35
36
|
:username => 'postgres',
|
36
37
|
:pgpass_file => nil,
|
37
38
|
:action => nil,
|
38
|
-
:database => nil
|
39
|
+
:database => nil,
|
40
|
+
:output => nil
|
39
41
|
}
|
40
42
|
|
41
43
|
def initialize(delegate, attrs = {})
|
@@ -52,7 +54,9 @@ module Masamune::Commands
|
|
52
54
|
args << '--host=%s' % @hostname if @hostname
|
53
55
|
args << '--username=%s' % @username if @username
|
54
56
|
args << '--no-password'
|
55
|
-
args <<
|
57
|
+
args << database
|
58
|
+
args << @options
|
59
|
+
args << output
|
56
60
|
args.flatten.compact
|
57
61
|
end
|
58
62
|
|
@@ -64,9 +68,21 @@ module Masamune::Commands
|
|
64
68
|
[@create_db_path]
|
65
69
|
when :drop
|
66
70
|
[@drop_db_path, '--if-exists']
|
71
|
+
when :dump
|
72
|
+
[@pg_dump_path, '--no-owner', '--no-privileges', '--oids', '--schema=public']
|
67
73
|
else
|
68
|
-
raise ArgumentError, ':action must be :create or :
|
74
|
+
raise ArgumentError, ':action must be :create, :drop, or :dump'
|
69
75
|
end
|
70
76
|
end
|
77
|
+
|
78
|
+
def database
|
79
|
+
return @database unless @action == :dump
|
80
|
+
'--dbname=%s' % @database
|
81
|
+
end
|
82
|
+
|
83
|
+
def output
|
84
|
+
return unless @action == :dump
|
85
|
+
'--file=%s' % @output if @output
|
86
|
+
end
|
71
87
|
end
|
72
88
|
end
|
@@ -109,9 +109,18 @@ class Masamune::DataPlan::Rule
|
|
109
109
|
matched_pattern.present? && matched_pattern[:rest].blank?
|
110
110
|
end
|
111
111
|
|
112
|
-
def
|
113
|
-
|
114
|
-
|
112
|
+
def bind_date_or_time(input = nil)
|
113
|
+
input_time =
|
114
|
+
case input
|
115
|
+
when Time, DateTime
|
116
|
+
input
|
117
|
+
when Date
|
118
|
+
input.to_time
|
119
|
+
else
|
120
|
+
raise ArgumentError, "Cannot bind_date_or_time with type #{input.class}"
|
121
|
+
end
|
122
|
+
output_time = tz.utc_to_local(input_time)
|
123
|
+
Masamune::DataPlan::Elem.new(self, output_time, options_for_elem)
|
115
124
|
end
|
116
125
|
|
117
126
|
def bind_input(input)
|
@@ -123,12 +132,12 @@ class Masamune::DataPlan::Rule
|
|
123
132
|
end
|
124
133
|
|
125
134
|
def unify(elem, rule)
|
126
|
-
rule.
|
135
|
+
rule.bind_date_or_time(elem.start_time)
|
127
136
|
end
|
128
137
|
|
129
138
|
def generate(start_time, stop_time)
|
130
139
|
return Set.new(to_enum(:generate, start_time, stop_time)) unless block_given?
|
131
|
-
instance =
|
140
|
+
instance = bind_date_or_time(start_time)
|
132
141
|
|
133
142
|
begin
|
134
143
|
yield instance
|
data/lib/masamune/schema/fact.rb
CHANGED
@@ -85,17 +85,28 @@ module Masamune::Schema
|
|
85
85
|
end
|
86
86
|
end
|
87
87
|
|
88
|
-
def partition_table(date)
|
89
|
-
|
88
|
+
def partition_table(date = nil)
|
89
|
+
return unless partition
|
90
|
+
return unless date
|
91
|
+
partition_range = partition_rule.bind_date_or_time(date)
|
90
92
|
@partition_tables ||= {}
|
91
93
|
@partition_tables[partition_range] ||= self.class.new(id: @id, store: store, columns: partition_table_columns, parent: self, range: partition_range, grain: grain, inherit: true)
|
92
94
|
end
|
93
95
|
|
96
|
+
def partition_tables(start_date = nil, stop_date = nil)
|
97
|
+
return unless partition
|
98
|
+
return unless start_date && stop_date
|
99
|
+
(start_date .. stop_date).each do |date|
|
100
|
+
next unless date.day == 1
|
101
|
+
yield partition_table(date)
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
94
105
|
def measures
|
95
106
|
columns.select { |_, column| column.measure }
|
96
107
|
end
|
97
108
|
|
98
|
-
def
|
109
|
+
def inheritance_constraints
|
99
110
|
return unless range
|
100
111
|
"CHECK (time_key >= #{range.start_time.to_i} AND time_key < #{range.stop_time.to_i})"
|
101
112
|
end
|
@@ -183,8 +183,13 @@ module Masamune::Schema
|
|
183
183
|
return to_enum(__method__).to_a.flatten.compact unless block_given?
|
184
184
|
columns.map do |_, column|
|
185
185
|
next if column.surrogate_key || column.ignore
|
186
|
-
if column.reference
|
187
|
-
|
186
|
+
if column.reference && column.reference.natural_keys.any?
|
187
|
+
column.reference.natural_keys.each do |join_column|
|
188
|
+
next if join_column.reference && join_column.natural_key
|
189
|
+
yield [column.reference, join_column]
|
190
|
+
end
|
191
|
+
elsif column.reference && column.reference.denormalized_columns.any?
|
192
|
+
column.reference.denormalized_columns.each do |join_column|
|
188
193
|
yield [column.reference, join_column]
|
189
194
|
end
|
190
195
|
else
|
@@ -26,6 +26,7 @@ require 'thor'
|
|
26
26
|
module Masamune::Tasks
|
27
27
|
class DumpThor < Thor
|
28
28
|
include Masamune::Thor
|
29
|
+
include Masamune::Actions::DateParse
|
29
30
|
include Masamune::Transform::DefineSchema
|
30
31
|
|
31
32
|
# FIXME need to add an unnecessary namespace until this issue is fixed:
|
@@ -35,9 +36,7 @@ module Masamune::Tasks
|
|
35
36
|
|
36
37
|
desc 'dump', 'Dump schema'
|
37
38
|
method_option :type, :enum => ['psql', 'hql'], :desc => 'Schema type', :default => 'psql'
|
38
|
-
method_option :
|
39
|
-
method_option :with_foreign_key, :type => :boolean, :desc => 'Dump schema with foreign key constraints', :default => true
|
40
|
-
method_option :with_unique_constraint, :type => :boolean, :desc => 'Dump schema with uniqueness constraints', :default => true
|
39
|
+
method_option :section, :enum => ['pre', 'post', 'all'], :desc => 'Schema section', :default => 'all'
|
41
40
|
def dump_exec
|
42
41
|
print_catalog
|
43
42
|
exit
|
@@ -49,10 +48,18 @@ module Masamune::Tasks
|
|
49
48
|
def print_catalog
|
50
49
|
case options[:type]
|
51
50
|
when 'psql'
|
52
|
-
puts define_schema(catalog, :postgres,
|
51
|
+
puts define_schema(catalog, :postgres, define_schema_options)
|
53
52
|
when 'hql'
|
54
|
-
puts define_schema(catalog, :hive)
|
53
|
+
puts define_schema(catalog, :hive, define_schema_options)
|
55
54
|
end
|
56
55
|
end
|
56
|
+
|
57
|
+
def define_schema_options
|
58
|
+
{
|
59
|
+
section: options[:section].to_sym,
|
60
|
+
start_date: start_date,
|
61
|
+
stop_date: stop_date
|
62
|
+
}.reject { |_, v| v.blank? }
|
63
|
+
end
|
57
64
|
end
|
58
65
|
end
|
data/lib/masamune/template.rb
CHANGED
@@ -0,0 +1,28 @@
|
|
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
|
+
<%- if target.parent -%>
|
24
|
+
ALTER TABLE <%= target.name %> INHERIT <%= target.parent.name %>;
|
25
|
+
<%- end -%>
|
26
|
+
<%- if target.inheritance_constraints -%>
|
27
|
+
ALTER TABLE <%= target.name %> ADD CONSTRAINT <%= target.name %>_time_key_check <%= target.inheritance_constraints %>;
|
28
|
+
<%- end -%>
|
@@ -35,11 +35,14 @@ module Masamune::Transform
|
|
35
35
|
operators += context.extra(:pre)
|
36
36
|
|
37
37
|
context.dimensions.each do |_, dimension|
|
38
|
-
operators << define_table(dimension, [], options)
|
38
|
+
operators << define_table(dimension, [], options[:section])
|
39
39
|
end
|
40
40
|
|
41
41
|
context.facts.each do |_, fact|
|
42
|
-
operators << define_table(fact, [], options)
|
42
|
+
operators << define_table(fact, [], options[:section])
|
43
|
+
fact.partition_tables(options[:start_date], options[:stop_date]) do |fact_partition_table|
|
44
|
+
operators << define_table(fact_partition_table, [], options[:section])
|
45
|
+
end
|
43
46
|
end
|
44
47
|
|
45
48
|
operators += context.extra(:post)
|
@@ -22,22 +22,22 @@
|
|
22
22
|
|
23
23
|
<%
|
24
24
|
files ||= []
|
25
|
-
with_index = locals.fetch(:with_index, true)
|
26
|
-
with_foreign_key = locals.fetch(:with_foreign_key, true)
|
27
|
-
with_unique_constraint = locals.fetch(:with_unique_constraint, true)
|
28
25
|
%>
|
29
26
|
|
30
27
|
<%- target.children.each do |child| -%>
|
31
28
|
<%= render 'define_table.psql.erb', target: child, **locals.except(:target, :files) %>
|
32
29
|
<%- end -%>
|
33
30
|
|
31
|
+
<%- if helper.define_types? %>
|
34
32
|
<%- target.enum_columns.each do |_, column| -%>
|
35
33
|
DO $$ BEGIN
|
36
34
|
IF NOT EXISTS (SELECT 1 FROM pg_type t WHERE LOWER(t.typname) = LOWER('<%= column.sql_type %>')) THEN
|
37
35
|
CREATE TYPE <%= column.sql_type %> AS ENUM (<%= column.values.map { |value| "'#{value}'" }.join(', ') %>);
|
38
36
|
END IF; END $$;
|
39
37
|
<%- end -%>
|
38
|
+
<%- end -%>
|
40
39
|
|
40
|
+
<%- if helper.define_sequences? %>
|
41
41
|
<%- target.sequence_columns.each do |_, column| -%>
|
42
42
|
DO $$ BEGIN
|
43
43
|
IF NOT EXISTS (SELECT 1 FROM pg_class c WHERE c.relname = '<%= column.sequence_id %>') THEN
|
@@ -45,7 +45,9 @@ CREATE SEQUENCE <%= column.sequence_id %>;
|
|
45
45
|
ALTER SEQUENCE <%= column.sequence_id %> RESTART <%= column.sequence_offset %>;
|
46
46
|
END IF; END $$;
|
47
47
|
<%- end -%>
|
48
|
+
<%- end -%>
|
48
49
|
|
50
|
+
<%- if helper.define_tables? %>
|
49
51
|
<%- if target.temporary? -%>
|
50
52
|
CREATE TEMPORARY TABLE IF NOT EXISTS <%= target.name %>
|
51
53
|
<%- else -%>
|
@@ -56,25 +58,29 @@ CREATE TABLE IF NOT EXISTS <%= target.name %>
|
|
56
58
|
<%= column.as_psql %><%= ',' unless last %>
|
57
59
|
<%- end -%>
|
58
60
|
);
|
61
|
+
<%- end -%>
|
59
62
|
|
60
|
-
<%-
|
63
|
+
<%- if helper.define_primary_keys? %>
|
61
64
|
DO $$ BEGIN
|
62
65
|
IF NOT EXISTS (SELECT 1 FROM pg_class c WHERE c.relname = '<%= target.name %>_pkey') THEN
|
63
66
|
ALTER TABLE <%= target.name %> ADD PRIMARY KEY (<%= target.primary_keys.map(&:name).join(', ') %>);
|
64
67
|
END IF; END $$;
|
65
68
|
<%- end -%>
|
66
69
|
|
67
|
-
<%- if
|
70
|
+
<%- if helper.define_foreign_keys? -%>
|
68
71
|
<%= render 'define_foreign_key.psql.erb', target: target %>
|
69
72
|
<%- end -%>
|
70
73
|
|
74
|
+
<%- if helper.define_sequences? -%>
|
71
75
|
<%- target.sequence_columns.each do |_, column| -%>
|
72
76
|
DO $$ BEGIN
|
73
77
|
IF NOT EXISTS (SELECT 1 WHERE sequence_owner('<%= column.sequence_id %>') = '<%= column.qualified_name %>') THEN
|
74
78
|
ALTER SEQUENCE <%= column.sequence_id %> OWNED BY <%= column.qualified_name %>;
|
75
79
|
END IF; END $$;
|
76
80
|
<%- end -%>
|
81
|
+
<%- end -%>
|
77
82
|
|
83
|
+
<%- if helper.load_files? -%>
|
78
84
|
<%- files.each do |file| -%>
|
79
85
|
<%-
|
80
86
|
copy_options = []
|
@@ -84,25 +90,33 @@ END IF; END $$;
|
|
84
90
|
-%>
|
85
91
|
COPY <%= target.name %> FROM '<%= file %>' WITH (<%= copy_options.join(", ") %>);
|
86
92
|
<%- end -%>
|
93
|
+
<%- end -%>
|
87
94
|
|
88
|
-
<%- if
|
95
|
+
<%- if helper.define_inheritance? -%>
|
96
|
+
<%= render 'define_inheritance.psql.erb', target: target %>
|
97
|
+
<%- end -%>
|
98
|
+
|
99
|
+
<%- if helper.define_unique_constraints? -%>
|
89
100
|
<%= render 'define_unique.psql.erb', target: target %>
|
90
101
|
<%- end -%>
|
91
102
|
|
92
|
-
<%- if
|
103
|
+
<%- if helper.define_indexes? -%>
|
93
104
|
<%= render 'define_index.psql.erb', target: target %>
|
94
105
|
<%- end -%>
|
95
106
|
|
107
|
+
<%- if helper.insert_rows? -%>
|
96
108
|
<% target.insert_rows.each do |row| %>
|
97
109
|
INSERT INTO <%= target.name %> (<%= row.insert_columns.join(', ') %>)
|
98
110
|
SELECT <%= row.insert_values.join(', ') %>
|
99
111
|
WHERE NOT EXISTS (SELECT 1 FROM <%= target.name %> WHERE <%= row.insert_constraints.join(' AND ') %>);
|
100
112
|
<%- end -%>
|
113
|
+
<%- end -%>
|
101
114
|
|
102
|
-
<%- if
|
115
|
+
<%- if helper.perform_analyze? -%>
|
103
116
|
ANALYZE <%= target.name %>;
|
104
117
|
<%- end -%>
|
105
118
|
|
119
|
+
<%- if helper.define_functions? -%>
|
106
120
|
<% target.aliased_rows.each do |row| %>
|
107
121
|
<%- row.natural_keys.each do |column| -%>
|
108
122
|
CREATE OR REPLACE FUNCTION <%= row.name(column) %>
|
@@ -118,3 +132,4 @@ RETURNS <%= target.surrogate_key.sql_type %> IMMUTABLE AS $$
|
|
118
132
|
$$ LANGUAGE SQL;
|
119
133
|
|
120
134
|
<%- end -%>
|
135
|
+
<%- end -%>
|
@@ -24,23 +24,114 @@ module Masamune::Transform
|
|
24
24
|
module DefineTable
|
25
25
|
extend ActiveSupport::Concern
|
26
26
|
|
27
|
-
def define_table(target, files = [],
|
27
|
+
def define_table(target, files = [], section = nil)
|
28
28
|
return if target.implicit
|
29
|
-
Operator.new(__method__, target: target, files: Masamune::Schema::Map.convert_files(files),
|
29
|
+
Operator.new(__method__, target: target, files: Masamune::Schema::Map.convert_files(files), section: section, helper: Helper, presenters: { postgres: Postgres, hive: Hive }).tap do |operator|
|
30
30
|
logger.debug("#{target.id}\n" + operator.to_s) if target.debug
|
31
31
|
end
|
32
32
|
end
|
33
33
|
|
34
|
+
class Helper < SimpleDelegator
|
35
|
+
def files
|
36
|
+
locals[:files]
|
37
|
+
end
|
38
|
+
|
39
|
+
def section
|
40
|
+
locals[:section] || :all
|
41
|
+
end
|
42
|
+
|
43
|
+
def define_types?
|
44
|
+
!post_section?
|
45
|
+
end
|
46
|
+
|
47
|
+
def define_tables?
|
48
|
+
!post_section?
|
49
|
+
end
|
50
|
+
|
51
|
+
def define_functions?
|
52
|
+
!post_section?
|
53
|
+
end
|
54
|
+
|
55
|
+
def define_sequences?
|
56
|
+
!post_section?
|
57
|
+
end
|
58
|
+
|
59
|
+
def define_primary_keys?
|
60
|
+
!pre_section? && !(target.temporary? || target.primary_keys.empty?)
|
61
|
+
end
|
62
|
+
|
63
|
+
def define_inheritance?
|
64
|
+
return false unless target.inherited?
|
65
|
+
return false if pre_section?
|
66
|
+
return true if post_section?
|
67
|
+
!target.delay_indexes?
|
68
|
+
end
|
69
|
+
|
70
|
+
def define_indexes?
|
71
|
+
return false if pre_section?
|
72
|
+
return true if post_section?
|
73
|
+
!target.delay_indexes?
|
74
|
+
end
|
75
|
+
|
76
|
+
def define_foreign_keys?
|
77
|
+
return false if pre_section?
|
78
|
+
return true if post_section?
|
79
|
+
!target.delay_foreign_keys?
|
80
|
+
end
|
81
|
+
|
82
|
+
def define_unique_constraints?
|
83
|
+
return false if pre_section?
|
84
|
+
return true if post_section?
|
85
|
+
!target.delay_unique_constraints?
|
86
|
+
end
|
87
|
+
|
88
|
+
def insert_rows?
|
89
|
+
!post_section?
|
90
|
+
end
|
91
|
+
|
92
|
+
def load_files?
|
93
|
+
all_section?
|
94
|
+
end
|
95
|
+
|
96
|
+
def perform_analyze?
|
97
|
+
return false if pre_section?
|
98
|
+
return true if post_section?
|
99
|
+
files.any? || target.insert_rows.any?
|
100
|
+
end
|
101
|
+
|
102
|
+
private
|
103
|
+
|
104
|
+
def all_section?
|
105
|
+
section == :all
|
106
|
+
end
|
107
|
+
|
108
|
+
def pre_section?
|
109
|
+
section == :pre
|
110
|
+
end
|
111
|
+
|
112
|
+
def post_section?
|
113
|
+
section == :post
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
34
117
|
class Postgres < SimpleDelegator
|
35
118
|
def children
|
36
119
|
super.map { |child| self.class.new(child) }
|
37
120
|
end
|
38
121
|
|
39
|
-
def
|
122
|
+
def inherited?
|
123
|
+
type == :fact && inheritance_constraints
|
124
|
+
end
|
125
|
+
|
126
|
+
def delay_indexes?
|
127
|
+
type == :fact
|
128
|
+
end
|
129
|
+
|
130
|
+
def delay_foreign_keys?
|
40
131
|
type == :fact
|
41
132
|
end
|
42
133
|
|
43
|
-
def
|
134
|
+
def delay_unique_constraints?
|
44
135
|
type == :fact
|
45
136
|
end
|
46
137
|
end
|