# File lib/activefacts/metamodel/extensions.rb, line 2157 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
class ActiveFacts::Metamodel::Component
Constants
- RANK_DISCRIMINATOR
- RANK_FOREIGN
- RANK_IDENT
- RANK_INDICATOR
- RANK_INJECTION
- RANK_MANDATORY
- RANK_MULTIPLE
- RANK_NON_MANDATORY
- RANK_SCOPING
- RANK_SUBTYPE
- RANK_SUPER
- RANK_SURROGATE
The ranking key of a component indicates its importance to its parent: Ranking assigns a total order, but is computed in groups:
- RANK_VALUE
Public Instance Methods
all_role()
click to toggle source
# File lib/activefacts/metamodel/extensions.rb, line 2229 def all_role [] end
comment()
click to toggle source
# File lib/activefacts/metamodel/extensions.rb, line 2241 def comment return '' unless parent ((c = parent.comment) != '' ? c +' and ' : '') + name end
data_type(context = DataType::DefaultContext.new)
click to toggle source
# File lib/activefacts/metamodel/datatypes.rb, line 201 def data_type context = DataType::DefaultContext.new case self when Indicator context.boolean_type when SurrogateKey type_name, options = *context.surrogate_type options ||= {} # Flag but disable auto-assignment for a surrogate that's an FK (assigned elsewhere) options[:auto_assign] ||= 'commit' options[:auto_assign] = nil if in_foreign_key options[:mandatory] = path_mandatory [ type_name, options ] when ValidFrom, ValueField, Mapping # 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} : {}) ] else raise "Can't make a column from #{component}" end end
depth()
click to toggle source
# File lib/activefacts/metamodel/extensions.rb, line 2199 def depth parent ? 1+parent.depth : 0 end
fork_to_new_parent(parent)
click to toggle source
# File lib/activefacts/metamodel/extensions.rb, line 2246 def fork_to_new_parent parent @constellation.fork self, guid: :new, parent: parent, injection_annotation: nil end
in_foreign_key()
click to toggle source
# File lib/activefacts/metamodel/datatypes.rb, line 197 def in_foreign_key all_foreign_key_field.detect{|fkf| fkf.foreign_key.source_composite == root} end
in_natural_index()
click to toggle source
# File lib/activefacts/metamodel/datatypes.rb, line 192 def in_natural_index natural_index = root.natural_index and natural_index.all_index_field.detect{|ixf| ixf.component == self} end
in_primary_index()
click to toggle source
# File lib/activefacts/metamodel/datatypes.rb, line 187 def in_primary_index primary_index = root.primary_index and primary_index.all_index_field.detect{|ixf| ixf.component == self} end
inspect()
click to toggle source
# File lib/activefacts/metamodel/extensions.rb, line 2203 def inspect "#{self.class.basename}" end
is_auto_assigned()
click to toggle source
# File lib/activefacts/metamodel/extensions.rb, line 2237 def is_auto_assigned false end
is_in_primary()
click to toggle source
# File lib/activefacts/metamodel/extensions.rb, line 2166 def is_in_primary !!(root and p = root.primary_index and p.all_index_field.detect{|f| f.component == self}) end
is_mandatory()
click to toggle source
# File lib/activefacts/metamodel/extensions.rb, line 2220 def is_mandatory parent.is_mandatory end
leaves()
click to toggle source
# File lib/activefacts/metamodel/extensions.rb, line 2212 def leaves self end
narrow_value_constraint(value_constraint, nested_value_constraint)
click to toggle source
# File lib/activefacts/metamodel/datatypes.rb, line 268 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()
click to toggle source
# File lib/activefacts/metamodel/extensions.rb, line 2170 def parent_entity_type parent && parent.object_type.is_a?(EntityType) && parent.object_type end
path()
click to toggle source
# File lib/activefacts/metamodel/extensions.rb, line 2216 def path (parent ? parent.path+[self] : [self]) end
path_mandatory()
click to toggle source
# File lib/activefacts/metamodel/extensions.rb, line 2224 def path_mandatory # REVISIT: is_mandatory && parent.path_mandatory end
primary_index_components()
click to toggle source
REVISIT: This should be a method on Composite
, called here as root.primary_index_components
rank_key()
click to toggle source
# File lib/activefacts/metamodel/extensions.rb, line 2082 def rank_key @rank_key ||= case self when SurrogateKey if is_identifying [RANK_SURROGATE] # an injected PK elsif injection_annotation [RANK_INJECTION, name] else [RANK_FOREIGN, 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 if injection_annotation [RANK_INJECTION, name] else [RANK_IDENT] end 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] elsif injection_annotation [RANK_INJECTION, name] 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 ValidFrom [RANK_INJECTION, name] when Mapping # bare Mappings are always injected if root.mapping.object_type == object_type [RANK_IDENT, 0] else [RANK_INJECTION, name] end else raise "unexpected #{self.class.basename} in Component#rank_key" end end
rank_kind()
click to toggle source
# File lib/activefacts/metamodel/extensions.rb, line 2176 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()
click to toggle source
# File lib/activefacts/metamodel/extensions.rb, line 2233 def rank_path (parent ? parent.rank_path+[ordinal] : [ordinal]) end
root()
click to toggle source
# File lib/activefacts/metamodel/extensions.rb, line 2195 def root parent.root end
show_trace()
click to toggle source
# File lib/activefacts/metamodel/extensions.rb, line 2207 def show_trace raise "Implemented in subclasses" # trace :composition, "#{ordinal ? "#{ordinal}: " : ''}#{inspect}#{name ? " (as #{name.inspect})" : ''}" end
uncache_rank_key()
click to toggle source
# File lib/activefacts/metamodel/extensions.rb, line 2078 def uncache_rank_key @rank_key = nil end