Class: DbAgile::Core::Schema::Logical::ForeignKey

Inherits:
Constraint show all
Defined in:
lib/dbagile/core/schema/logical/constraint/foreign_key.rb

Instance Attribute Summary

Attributes inherited from Part

#definition, #name

Attributes inherited from SchemaObject

#parent, #status

Instance Method Summary collapse

Methods inherited from Constraint

#candidate_key?, factor, #foreign_key?, #primary_key?

Methods inherited from Part

#_sanity_check, #dup, #initialize, #look_same_as?, #to_s, #visit

Methods inherited from SchemaObject

#ancestors, #attribute?, #builder_args, #builder_handler, #candidate_key?, #composite?, #constraint?, #foreign_key?, #index?, #logical?, #outside_dependencies, #outside_dependents, #part?, #physical?, #primary_key?, #relation_variable, #relvar?, #relview?, #schema

Constructor Details

This class inherits a constructor from DbAgile::Core::Schema::Part

Instance Method Details

#_semantics_check(clazz, errors) ⇒ Object

See Also:



55
56
57
58
59
60
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
# File 'lib/dbagile/core/schema/logical/constraint/foreign_key.rb', line 55

def _semantics_check(clazz, errors)
  failed = false
  
  # 1) check source and target relvars
  if (srv = source_relvar).nil?
    raise DbAgile::SchemaInternalError, "Foreign key without source relvar"
  end
  if (trv = target_relvar).nil?
    code = clazz::InvalidForeignKey | clazz::NoSuchRelvar
    errors.add_error(self, code, :relvar_name => definition[:references])
    failed = true
  end
  return if failed
  
  # 2) Both exist, check source attributes
  if !srv.heading.has_attributes?(definition[:attributes])
    code = clazz::InvalidForeignKey | clazz::NoSuchRelvarAttributes
    errors.add_error(self, code, :relvar_name => srv.name,
                                 :attributes  => definition[:attributes])
    failed = true
  end
  return if failed
  
  # 3) Check target key existence and kind now
  trg_key = self.target_key
  if trg_key.nil? or not(trg_key.candidate_key?)
    code = clazz::InvalidForeignKey | clazz::NoSuchCandidateKey
    errors.add_error(self, code, :constraint_name => definition[:key])
    failed = true
  end
  return if failed
  
  source_attrs, target_attrs = source_attributes, trg_key.key_attributes
  if source_attrs.size != target_attrs.size
    code = clazz::InvalidForeignKey | clazz::TargetKeyMismatch
    errors.add_error(self, code, :constraint_name => definition[:key])
  elsif source_attrs.collect{|a| a.domain} != target_attrs.collect{|a| a.domain}
    code = clazz::InvalidForeignKey | clazz::TargetKeyMismatch
    errors.add_error(self, code, :constraint_name => definition[:key])
  end
end

#dependencies(include_parent = false) ⇒ Object

See Also:



44
45
46
47
48
# File 'lib/dbagile/core/schema/logical/constraint/foreign_key.rb', line 44

def dependencies(include_parent = false)
  deps = source_attributes + [ target_key ]
  deps << parent if include_parent
  deps
end

#source_attributesObject

Collects referencing attributes on the source relvar



18
19
20
21
# File 'lib/dbagile/core/schema/logical/constraint/foreign_key.rb', line 18

def source_attributes
  rv = source_relvar
  definition[:attributes].collect{|attr_name| rv.heading[attr_name]}
end

#source_relvarObject Also known as: referencing_relvar

Returns relation variable on which this foreign key is installed.



12
13
14
# File 'lib/dbagile/core/schema/logical/constraint/foreign_key.rb', line 12

def source_relvar
  relation_variable
end

#target_keyObject

Collects referencing attributes on the source relvar



30
31
32
33
34
35
36
37
# File 'lib/dbagile/core/schema/logical/constraint/foreign_key.rb', line 30

def target_key
  rv = target_relvar
  if definition.key?(:key)
    rv.constraints.constraint_by_name(definition[:key])
  else
    rv.constraints.primary_key
  end
end

#target_relvarObject Also known as: referenced_relvar

Returns target relation variable (aka) referenced_relvar



24
25
26
# File 'lib/dbagile/core/schema/logical/constraint/foreign_key.rb', line 24

def target_relvar
  schema.logical.relation_variable(definition[:references])
end

#to_yaml(opts = {}) ⇒ Object

Delegation pattern on YAML flushing



102
103
104
105
106
107
108
109
110
111
112
113
114
115
# File 'lib/dbagile/core/schema/logical/constraint/foreign_key.rb', line 102

def to_yaml(opts = {})
  YAML::quick_emit(self, opts){|out|
    defn = definition
    attributes = Schema::Builder::Coercion::unsymbolize_array(definition[:attributes])
    references = definition[:references].to_s
    key        = definition.key?(:key) ? definition[:key].to_s : nil
    out.map("tag:yaml.org,2002:map", :inline ) do |map|
      map.add('type', definition[:type])
      map.add('attributes', attributes)
      map.add('references', definition[:references].to_s)
      map.add('key', key) unless key.nil?
    end
  }
end