lib/activefacts/rmap/foreignkey.rb in activefacts-rmap-1.8.1 vs lib/activefacts/rmap/foreignkey.rb in activefacts-rmap-1.8.2
- old
+ new
@@ -26,66 +26,66 @@
@from, @to, @references, @from_columns, @to_columns =
from, to, references, from_columns, to_columns
end
def describe
- "foreign key from #{from.name}(#{from_columns.map{|c| c.name}*', '}) to #{to.name}(#{to_columns.map{|c| c.name}*', '})"
+ "foreign key from #{from.name}(#{from_columns.map{|c| c.name}*', '}) to #{to.name}(#{to_columns.map{|c| c.name}*', '})"
end
def verbalised_path reverse = false
- # REVISIT: This should be a proper join path verbalisation:
- refs = reverse ? references.reverse : references
- refs.map do |r|
- r.verbalised_path reverse
- end * ' and '
+ # REVISIT: This should be a proper join path verbalisation:
+ refs = reverse ? references.reverse : references
+ refs.map do |r|
+ r.verbalised_path reverse
+ end * ' and '
end
# Which references are absorbed into the "from" table?
def precursor_references
- fk_jump = @references.detect(&:fk_jump)
- jump_index = @references.index(fk_jump)
- @references[0, jump_index]
+ fk_jump = @references.detect(&:fk_jump)
+ jump_index = @references.index(fk_jump)
+ @references[0, jump_index]
end
# Which references are absorbed into the "to" table?
def following_references
- fk_jump = @references.detect(&:fk_jump)
- jump_index = @references.index(fk_jump)
- fk_jump != @references.last ? @references[jump_index+1..-1] : []
+ fk_jump = @references.detect(&:fk_jump)
+ jump_index = @references.index(fk_jump)
+ fk_jump != @references.last ? @references[jump_index+1..-1] : []
end
def jump_reference
- @references.detect(&:fk_jump)
+ @references.detect(&:fk_jump)
end
def to_name
- p = precursor_references
- f = following_references
- j = jump_reference
+ p = precursor_references
+ f = following_references
+ j = jump_reference
- @references.last.to_names +
- (p.empty? && f.empty? ? [] : ['via'] + p.map{|r| r.to_names}.flatten + f.map{|r| r.from_names}.flatten)
+ @references.last.to_names +
+ (p.empty? && f.empty? ? [] : ['via'] + p.map{|r| r.to_names}.flatten + f.map{|r| r.from_names}.flatten)
end
# The from_name is the role name of the table with the FK, viewed from the other end
# When there are no precursor_references or following_references, it's the jump_reference.from_names
# REVISIT: I'm still working out what to do with precursor_references and following_references
def from_name
- p = precursor_references
- f = following_references
- j = jump_reference
+ p = precursor_references
+ f = following_references
+ j = jump_reference
- # pluralise unless j.is_one_to_one
+ # pluralise unless j.is_one_to_one
- # REVISIT: references[0].from_names is where the FK lives; but the object of interest may be an absorbed subclass which we should use here instead:
- # REVISIT: Should crunch superclasses in subtype traversals
- # REVISIT: Need to add "_as_rolename" where rolename is not to.name
+ # REVISIT: references[0].from_names is where the FK lives; but the object of interest may be an absorbed subclass which we should use here instead:
+ # REVISIT: Should crunch superclasses in subtype traversals
+ # REVISIT: Need to add "_as_rolename" where rolename is not to.name
- [
- @references[0].from_names,
- (p.empty? && f.empty? ? [] : ['via'] + p.map{|r| r.to_names}.flatten + f.map{|r| r.from_names}.flatten)
- ]
+ [
+ @references[0].from_names,
+ (p.empty? && f.empty? ? [] : ['via'] + p.map{|r| r.to_names}.flatten + f.map{|r| r.from_names}.flatten)
+ ]
end
end
end
@@ -101,86 +101,86 @@
next array if absorbed_via && TypeInheritance === absorbed_via.fact_type
# Ignore the case where a subtype is absorbed elsewhere:
# REVISIT: Disabled, as this should never happen.
# next array if ref.to.absorbed_via != ref.fact_type
end
- ref.fk_jump = true
+ ref.fk_jump = true
array << [ref]
elsif ref.is_absorbing or (ref.to && !ref.to.is_table)
- trace :fk, "getting fks absorbed into #{name} via #{ref}" do
- ref.to.all_absorbed_foreign_key_reference_path.each do |aref|
- array << aref.insert(0, ref)
- end
- end
+ trace :fk, "getting fks absorbed into #{name} via #{ref}" do
+ ref.to.all_absorbed_foreign_key_reference_path.each do |aref|
+ array << aref.insert(0, ref)
+ end
+ end
end
array
end
end
def foreign_keys_to
- @foreign_keys_to ||= []
+ @foreign_keys_to ||= []
end
# Return an array of all the foreign keys from this table
def foreign_keys
# Get the ForeignKey object for each absorbed reference path
- @foreign_keys ||=
- begin
- fk_ref_paths = all_absorbed_foreign_key_reference_path
- fk_ref_paths.map do |fk_ref_path|
- trace :fk, "\nFK: " + fk_ref_path.map{|fk_ref| fk_ref.reading }*" and " do
+ @foreign_keys ||=
+ begin
+ fk_ref_paths = all_absorbed_foreign_key_reference_path
+ fk_ref_paths.map do |fk_ref_path|
+ trace :fk, "\nFK: " + fk_ref_path.map{|fk_ref| fk_ref.reading }*" and " do
- from_columns = (columns||all_columns({})).select{|column|
- column.references[0...fk_ref_path.size] == fk_ref_path
- }
- trace :fk, "from_columns = #{from_columns.map { |column| column.name }*", "}"
+ from_columns = (columns||all_columns({})).select{|column|
+ column.references[0...fk_ref_path.size] == fk_ref_path
+ }
+ trace :fk, "from_columns = #{from_columns.map { |column| column.name }*", "}"
- # Figure out absorption on the target end:
- to = fk_ref_path.last.to
- if to.absorbed_via
- trace :fk, "Reference target #{fk_ref_path.last.to.name} is absorbed via:" do
- while (r = to.absorbed_via)
- m = r.reversed
- trace :fk, "#{m.reading}"
- fk_ref_path << m
- to = m.from == to ? m.to : m.from
- end
- trace :fk, "Absorption ends at #{to.name}"
- end
- end
+ # Figure out absorption on the target end:
+ to = fk_ref_path.last.to
+ if to.absorbed_via
+ trace :fk, "Reference target #{fk_ref_path.last.to.name} is absorbed via:" do
+ while (r = to.absorbed_via)
+ m = r.reversed
+ trace :fk, "#{m.reading}"
+ fk_ref_path << m
+ to = m.from == to ? m.to : m.from
+ end
+ trace :fk, "Absorption ends at #{to.name}"
+ end
+ end
- # REVISIT: This test may no longer be necessary
- raise "REVISIT: #{fk_ref_path.inspect} is bad" unless to and to.columns
+ # REVISIT: This test may no longer be necessary
+ raise "REVISIT: #{fk_ref_path.inspect} is bad" unless to and to.columns
- # REVISIT: This fails for absorbed subtypes having their own identification.
- # Check the CompanyDirectorEmployee model for example, EmployeeManagerNr -> Person (should reference EmployeeNr)
- # Need to use the absorbed identifier_columns of the subtype,
- # not the columns of the supertype that absorbs it.
- # But in general, that isn't going to work because in most DBMS
- # there's no suitable uniquen index on the subtype's identifier_columns
+ # REVISIT: This fails for absorbed subtypes having their own identification.
+ # Check the CompanyDirectorEmployee model for example, EmployeeManagerNr -> Person (should reference EmployeeNr)
+ # Need to use the absorbed identifier_columns of the subtype,
+ # not the columns of the supertype that absorbs it.
+ # But in general, that isn't going to work because in most DBMS
+ # there's no suitable uniquen index on the subtype's identifier_columns
- to_columns = fk_ref_path[-1].to.identifier_columns
+ to_columns = fk_ref_path[-1].to.identifier_columns
- # Put the column pairs in the correct order. They MUST be in the order they appear in the primary key
- froms, tos = from_columns.zip(to_columns).sort_by { |pair|
- to_columns.index(pair[1])
- }.transpose
+ # Put the column pairs in the correct order. They MUST be in the order they appear in the primary key
+ froms, tos = from_columns.zip(to_columns).sort_by { |pair|
+ to_columns.index(pair[1])
+ }.transpose
- fk = ActiveFacts::RMap::ForeignKey.new(self, to, fk_ref_path, froms, tos)
- to.foreign_keys_to << fk
- fk
- end
- end.
- sort_by do |fk|
- # Put the foreign keys in a defined order:
-# debugger if !fk.to_columns || fk.to_columns.include?(nil) || !fk.from_columns || fk.from_columns.include?(nil)
- [ fk.to.name,
- fk.to_columns.map{|col| col.name(nil).sort},
- fk.from_columns.map{|col| col.name(nil).sort}
- ]
- end
- end
+ fk = ActiveFacts::RMap::ForeignKey.new(self, to, fk_ref_path, froms, tos)
+ to.foreign_keys_to << fk
+ fk
+ end
+ end.
+ sort_by do |fk|
+ # Put the foreign keys in a defined order:
+# debugger if !fk.to_columns || fk.to_columns.include?(nil) || !fk.from_columns || fk.from_columns.include?(nil)
+ [ fk.to.name,
+ fk.to_columns.map{|col| col.name(nil).sort},
+ fk.from_columns.map{|col| col.name(nil).sort}
+ ]
+ end
+ end
end
end
end
end