masamune 0.13.0 → 0.13.1
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.
- 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
|