Class: ActiveFacts::Metamodel::Component
- Inherits:
-
Object
- Object
- ActiveFacts::Metamodel::Component
- Defined in:
- lib/activefacts/metamodel/datatypes.rb,
lib/activefacts/metamodel/metamodel.rb,
lib/activefacts/metamodel/extensions.rb
Direct Known Subclasses
Constant Summary collapse
- RANK_SURROGATE =
The ranking key of a component indicates its importance to its parent: Ranking assigns a total order, but is computed in groups:
0- RANK_SUPER =
Supertypes, with the identifying supertype first, others alphabetical
1- RANK_IDENT =
Identifying components (absorptions, indicator), in order of the identifier
2- RANK_VALUE =
A ValueField
3- RANK_INJECTION =
Injections, in alphabetical order
4- RANK_DISCRIMINATOR =
Discriminator components, in alphabetical order
5- RANK_FOREIGN =
REVISIT: Foreign key components
6- RANK_INDICATOR =
Indicators in alphabetical order
7- RANK_MANDATORY =
Absorption: unique mandatory
8- RANK_NON_MANDATORY =
Absorption: unique optional
9- RANK_MULTIPLE =
Absorption: manifold
10- RANK_SUBTYPE =
Subtypes in alphabetical order
11- RANK_SCOPING =
Scoping in alphabetical order
12
Instance Method Summary collapse
- #all_role ⇒ Object
- #comment ⇒ Object
- #data_type(context = DataType::DefaultContext.new) ⇒ Object
- #depth ⇒ Object
- #fork_to_new_parent(parent) ⇒ Object
- #in_foreign_key ⇒ Object
- #in_primary_index ⇒ Object
- #inspect ⇒ Object
- #is_auto_assigned ⇒ Object
- #is_mandatory ⇒ Object
- #leaves ⇒ Object
- #narrow_value_constraint(value_constraint, nested_value_constraint) ⇒ Object
- #parent_entity_type ⇒ Object
- #path ⇒ Object
- #path_mandatory ⇒ Object
-
#primary_index_components ⇒ Object
REVISIT: This should be a method on Composite, called here as root.primary_index_components.
- #rank_key ⇒ Object
- #rank_kind ⇒ Object
- #rank_path ⇒ Object
- #root ⇒ Object
- #show_trace ⇒ Object
- #uncache_rank_key ⇒ Object
Instance Method Details
#all_role ⇒ Object
2180 2181 2182 |
# File 'lib/activefacts/metamodel/extensions.rb', line 2180 def all_role [] end |
#comment ⇒ Object
2192 2193 2194 2195 |
# File 'lib/activefacts/metamodel/extensions.rb', line 2192 def comment return '' unless parent ((c = parent.comment) != '' ? c +' and ' : '') + name end |
#data_type(context = DataType::DefaultContext.new) ⇒ Object
187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 |
# File 'lib/activefacts/metamodel/datatypes.rb', line 187 def data_type context = DataType::DefaultContext.new case self when Indicator context.boolean_type when SurrogateKey [ context.surrogate_type, { auto_assign: ((in_primary_index && !in_foreign_key) ? "commit" : nil), mandatory: path_mandatory } ] when ValidFrom object_type.name when ValueField, Absorption # Walk up the entity type identifiers (must be single-part) to a value type: vt = self.object_type while vt.is_a?(EntityType) rr = vt.preferred_identifier.role_sequence.all_role_ref.single raise "Can't produce a column for composite #{inspect}" unless rr value_constraint = narrow_value_constraint(value_constraint, rr.role.role_value_constraint) vt = rr.role.object_type end raise "A column can only be produced from a ValueType not a #{vt.class.basename}" unless vt.is_a?(ValueType) if is_a?(Absorption) value_constraint = narrow_value_constraint(value_constraint, child_role.role_value_constraint) end # Gather up the characteristics from the value supertype hierarchy: is_auto_assigned = false stype = vt begin vt = stype # REVISIT: Check for length and scale shortening length ||= vt.length scale ||= vt.scale is_auto_assigned ||= vt.is_auto_assigned unless parent.parent and parent.foreign_key # No need to enforce value constraints that are already enforced by a foreign key value_constraint = narrow_value_constraint(value_constraint, vt.value_constraint) end end while stype = vt.supertype auto_assign = if is_auto_assigned if in_primary_index and !in_foreign_key {auto_assign: is_auto_assigned} # It's auto-assigned here else {auto_assign: nil} # It's auto-assigned elsewhere end else {} # It's not auto-assigned end [ vt.name, (length ? {length: length} : {}). merge!(scale ? {scale: scale} : {}). merge!(auto_assign). merge!({mandatory: path_mandatory}). merge!(value_constraint ? {value_constraint: value_constraint} : {}) ] when Injection object_type.name else raise "Can't make a column from #{component}" end end |
#depth ⇒ Object
2150 2151 2152 |
# File 'lib/activefacts/metamodel/extensions.rb', line 2150 def depth parent ? 1+parent.depth : 0 end |
#fork_to_new_parent(parent) ⇒ Object
2197 2198 2199 |
# File 'lib/activefacts/metamodel/extensions.rb', line 2197 def fork_to_new_parent parent @constellation.fork self, guid: :new, parent: parent end |
#in_foreign_key ⇒ Object
183 184 185 |
# File 'lib/activefacts/metamodel/datatypes.rb', line 183 def in_foreign_key all_foreign_key_field.detect{|fkf| fkf.foreign_key.source_composite == root} end |
#in_primary_index ⇒ Object
178 179 180 181 |
# File 'lib/activefacts/metamodel/datatypes.rb', line 178 def in_primary_index primary_index = root.primary_index and primary_index.all_index_field.detect{|ixf| ixf.component == self} end |
#inspect ⇒ Object
2154 2155 2156 |
# File 'lib/activefacts/metamodel/extensions.rb', line 2154 def inspect "#{self.class.basename}" end |
#is_auto_assigned ⇒ Object
2188 2189 2190 |
# File 'lib/activefacts/metamodel/extensions.rb', line 2188 def is_auto_assigned false end |
#is_mandatory ⇒ Object
2171 2172 2173 |
# File 'lib/activefacts/metamodel/extensions.rb', line 2171 def is_mandatory parent.is_mandatory end |
#leaves ⇒ Object
2163 2164 2165 |
# File 'lib/activefacts/metamodel/extensions.rb', line 2163 def leaves self end |
#narrow_value_constraint(value_constraint, nested_value_constraint) ⇒ Object
258 259 260 261 |
# File 'lib/activefacts/metamodel/datatypes.rb', line 258 def narrow_value_constraint(value_constraint, nested_value_constraint) # REVISIT: Need to calculate the constrant narrowing return nested_value_constraint || value_constraint end |
#parent_entity_type ⇒ Object
2121 2122 2123 2124 2125 |
# File 'lib/activefacts/metamodel/extensions.rb', line 2121 def parent_entity_type parent && parent.object_type.is_a?(EntityType) && parent.object_type end |
#path ⇒ Object
2167 2168 2169 |
# File 'lib/activefacts/metamodel/extensions.rb', line 2167 def path (parent ? parent.path+[self] : [self]) end |
#path_mandatory ⇒ Object
2175 2176 2177 2178 |
# File 'lib/activefacts/metamodel/extensions.rb', line 2175 def path_mandatory # REVISIT: is_mandatory && parent.path_mandatory end |
#primary_index_components ⇒ Object
REVISIT: This should be a method on Composite, called here as root.primary_index_components
2112 2113 2114 2115 2116 2117 2118 2119 |
# File 'lib/activefacts/metamodel/extensions.rb', line 2112 def primary_index_components root and ix = root.primary_index and # Primary index has been decided root.primary_index.all_index_field.size > 0 and # has been populated and ix = root.primary_index and ixfs = ix.all_index_field.sort_by(&:ordinal) and ixfs.map(&:component) end |
#rank_key ⇒ Object
2050 2051 2052 2053 2054 2055 2056 2057 2058 2059 2060 2061 2062 2063 2064 2065 2066 2067 2068 2069 2070 2071 2072 2073 2074 2075 2076 2077 2078 2079 2080 2081 2082 2083 2084 2085 2086 2087 2088 2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099 2100 2101 2102 2103 2104 2105 2106 2107 2108 2109 |
# File 'lib/activefacts/metamodel/extensions.rb', line 2050 def rank_key @rank_key ||= case self when SurrogateKey if [RANK_SURROGATE] # an injected PK else [RANK_MANDATORY, name] # an FK end when Indicator if (p = parent_entity_type) and p.preferred_identifier and (position = p.rank_in_preferred_identifier(role.base_role)) [RANK_IDENT, position] # An identifying unary else [RANK_INDICATOR, name || role.name] # A non-identifying unary end when Discriminator [RANK_DISCRIMINATOR, name || child_role.name] when ValueField [RANK_IDENT] when Injection [RANK_INJECTION, name] # REVISIT: Injection not fully elaborated. A different sub-key for ranking may be needed when Absorption if is_type_inheritance # We are traversing a type inheritance fact type. Is this object_type the subtype or supertype? if is_supertype_absorption # What's the rank of this supertype? tis = parent_role.object_type.all_type_inheritance_as_subtype.sort_by{|ti| ti.provides_identification ? '' : ti.supertype.name } [RANK_SUPER, child_role.fact_type.provides_identification ? 0 : 1+tis.index(parent_role.fact_type)] else # What's the rank of this subtype? tis = parent_role.object_type.all_type_inheritance_as_supertype.sort_by{|ti| ti.subtype.name } [RANK_SUBTYPE, tis.index(parent_role.fact_type)] end elsif (p = parent_entity_type) and (position = p.rank_in_preferred_identifier(child_role.base_role)) [RANK_IDENT, position] else if parent_role.is_unique [parent_role.is_mandatory ? RANK_MANDATORY : RANK_NON_MANDATORY, name || child_role.name] else [RANK_MULTIPLE, name || child_role.name, parent_role.name] end end when Scoping [RANK_SCOPING, name || object_type.name] when Mapping [ name ] else raise "unexpected #{self.class.basename} in Component#rank_key" end end |
#rank_kind ⇒ Object
2127 2128 2129 2130 2131 2132 2133 2134 2135 2136 2137 2138 2139 2140 2141 2142 2143 2144 |
# File 'lib/activefacts/metamodel/extensions.rb', line 2127 def rank_kind return "top" unless parent # E.g. a Mapping that is a Composite case rank_key[0] when RANK_SURROGATE; "surrogate" when RANK_SUPER; "supertype" when RANK_IDENT; "existential" when RANK_VALUE; "self-value" when RANK_INJECTION; "injection" when RANK_DISCRIMINATOR;"discriminator" when RANK_FOREIGN; "foreignkey" when RANK_INDICATOR; "indicator" when RANK_MANDATORY; "mandatory" when RANK_NON_MANDATORY;"optional" when RANK_MULTIPLE; "multiple" when RANK_SUBTYPE; "subtype" when RANK_SCOPING; "scoping" end end |
#rank_path ⇒ Object
2184 2185 2186 |
# File 'lib/activefacts/metamodel/extensions.rb', line 2184 def rank_path (parent ? parent.rank_path+[ordinal] : [ordinal]) end |
#root ⇒ Object
2146 2147 2148 |
# File 'lib/activefacts/metamodel/extensions.rb', line 2146 def root parent.root end |
#show_trace ⇒ Object
2158 2159 2160 2161 |
# File 'lib/activefacts/metamodel/extensions.rb', line 2158 def show_trace raise "Implemented in subclasses" # trace :composition, "#{ordinal ? "#{ordinal}: " : ''}#{inspect}#{name ? " (as #{name.inspect})" : ''}" end |
#uncache_rank_key ⇒ Object
2046 2047 2048 |
# File 'lib/activefacts/metamodel/extensions.rb', line 2046 def uncache_rank_key @rank_key = nil end |