Class: ActiveFacts::Persistence::Column

Inherits:
Object
  • Object
show all
Includes:
Metamodel
Defined in:
lib/activefacts/persistence/columns.rb

Instance Method Summary collapse

Constructor Details

#initialize(reference = nil) ⇒ Column

:nodoc:



25
26
27
# File 'lib/activefacts/persistence/columns.rb', line 25

def initialize(reference = nil) #:nodoc:
  references << reference if reference
end

Instance Method Details

#absorption_levelObject

How many of the initial references are involved in full absorption of an EntityType into this column’s table



45
46
47
48
49
50
51
52
# File 'lib/activefacts/persistence/columns.rb', line 45

def absorption_level
  l = 0
  @references.detect do |ref|
    l += 1 if ref.is_absorbing
    false
  end
  l
end

#absorption_referencesObject

All references up to and including the first non-absorbing reference



35
36
37
38
39
40
41
42
# File 'lib/activefacts/persistence/columns.rb', line 35

def absorption_references
  @references.inject([]) do |array, ref|
    array << ref
    # puts "Column #{name} spans #{ref}, #{ref.is_absorbing ? "" : "not "} absorbing (#{ref.to.name} absorbs via #{ref.to.absorbed_via.inspect})"
    break array unless ref.is_absorbing
    array
  end
end

#commentObject

The comment is the readings from the References expressed as a join



144
145
146
147
148
149
150
# File 'lib/activefacts/persistence/columns.rb', line 144

def comment
  @references.map do |ref|
    (ref.is_mandatory ? "" : "maybe ") +
    (ref.fact_type && ref.fact_type.entity_type ? ref.fact_type.entity_type.name+" is where " : "") +
    ref.reading
  end * " and "
end

#is_auto_assignedObject

Is this column an auto-assigned value type?



115
116
117
# File 'lib/activefacts/persistence/columns.rb', line 115

def is_auto_assigned
  (to = references[-1].to) && to.is_auto_assigned
end

#is_mandatoryObject

Is this column mandatory or nullable?



110
111
112
# File 'lib/activefacts/persistence/columns.rb', line 110

def is_mandatory
  !@references.detect{|ref| !ref.is_mandatory}
end

#name(joiner = "") ⇒ Object

A Column name is a sequence of names (derived from the to_roles of the References) joined by a joiner string (pass nil to get the original array of names)



61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
# File 'lib/activefacts/persistence/columns.rb', line 61

def name(joiner = "")
  last_names = []
  names = @references.
    reject do |ref|
      # Skip any object after the first which is identified by this reference
      ref != @references[0] and
        !ref.fact_type.is_a?(TypeInheritance) and
        ref.to and
        ref.to.is_a?(EntityType) and
        (role_ref = ref.to.preferred_identifier.role_sequence.all_role_ref.single) and
        role_ref.role == ref.from_role
    end.
    inject([]) do |a, ref|
      names = ref.to_names

      # When traversing type inheritances, keep the subtype name, not the supertype names as well:
      if a.size > 0 && ref.fact_type.is_a?(TypeInheritance)
        next a if ref.to != ref.fact_type.subtype  # Did we already have the subtype?
        last_names.size.times { a.pop }   # Remove the last names added
      elsif last_names.last && last_names.last == names[0][0...last_names.last.size] 
        # When Xyz is followed by XyzID, truncate that to just ID
        names[0] = names[0][last_names.last.size..-1]
      elsif last_names.last == names[0]
        # Same, but where an underscore split up the words
        names.shift
      end

      # Where the last name is like a reference mode but the preceeding name isn't the identified concept,
      # strip it down (so turn Driver.PartyID into Driver.ID for example):
      if a.size > 0 and
          (et = ref.from).is_a?(EntityType) and
          (role_ref = et.preferred_identifier.role_sequence.all_role_ref.single) and
          role_ref.role == ref.to_role and
          names[0][0...et.name.size].downcase == et.name.downcase
        names[0] = names[0][et.name.size..-1]
        names.shift if names[0] == ""
      end

      last_names = names

      a += names
      a
    end

  name_array = names.map{|n| n.sub(/^[a-z]/){|s| s.upcase}}
  joiner ? name_array * joiner : name_array
end

#prepend(reference) ⇒ Object

:nodoc:



54
55
56
57
# File 'lib/activefacts/persistence/columns.rb', line 54

def prepend reference           #:nodoc:
  references.insert 0, reference
  self
end

#referencesObject

A Column is created from a path through an array of References to a ValueType



30
31
32
# File 'lib/activefacts/persistence/columns.rb', line 30

def references
  @references ||= []
end

#to_sObject

:nodoc:



152
153
154
# File 'lib/activefacts/persistence/columns.rb', line 152

def to_s  #:nodoc:
  "#{@references[0].from.name} column #{name('.')}"
end

#typeObject

What’s the underlying SQL data type of this column?



120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
# File 'lib/activefacts/persistence/columns.rb', line 120

def type
  params = {}
  restrictions = []
  return ["BIT", params, restrictions] if references[-1].is_unary   # It's a unary

  # Add a role value restriction
  # REVISIT: Can add join-role-value-restrictions here, if we ever provide a way to define them
  if references[-1].to_role && references[-1].to_role.role_value_restriction
    restrictions << references[-1].to_role.role_value_restriction
  end

  vt = references[-1].is_self_value ? references[-1].from : references[-1].to
  params[:length] ||= vt.length if vt.length.to_i != 0
  params[:scale] ||= vt.scale if vt.scale.to_i != 0
  while vt.supertype
    params[:length] ||= vt.length if vt.length.to_i != 0
    params[:scale] ||= vt.scale if vt.scale.to_i != 0
    restrictions << vt.value_restriction if vt.value_restriction
    vt = vt.supertype
  end
  return [vt.name, params, restrictions]
end