Class: Alf::Relation

Inherits:
Object
  • Object
show all
Includes:
Algebra::Operand, Lang::ObjectOriented, Enumerable
Defined in:
lib/alf/relation.rb

Overview

Defines an in-memory relation data structure.

A relation is a set of tuples; a tuple is a set of attribute (name, value) pairs. The class implements such a data structure with full relational algebra installed as instance methods.

Relation values can be obtained in various ways, for example by invoking a relational operator on an existing relation. Relation literals are simply constructed as follows:

Alf::Relation([
  # ... a comma list of ruby hashes ...
])

See main Alf documentation about relational operators.

Constant Summary collapse

DUM_TYPE =
DEE_TYPE = Relation[{}]
DUM =
DUM_TYPE.new([])
DEE =
DEE_TYPE.new([{}])

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Lang::ObjectOriented

new

Methods included from Lang::ObjectOriented::RenderingMethods

def_renderer_method, #to_a, #to_array

Methods included from Lang::ObjectOriented::AlgebraMethods

#!~, #&, #*, #+, #-, #=~, def_operator_method, #tuple_extract

Methods included from Lang::ObjectOriented::AggregationMethods

def_aggregator_method

Methods included from Algebra::Operand

#attr_list, coerce, #resulting_type, #to_ascii_tree, #type_check

Constructor Details

#initialize(tuples) ⇒ Relation

Returns a new instance of Relation


26
27
28
29
# File 'lib/alf/relation.rb', line 26

def initialize(tuples)
  tuple_type = self.class.to_tuple_type
  super(tuples.map{|x| tuple_type.coerce(x) }.to_set)
end

Class Method Details

.emptyObject


50
51
52
# File 'lib/alf/relation.rb', line 50

def self.empty
  @empty ||= new([].to_set)
end

Instance Method Details

#[](*args) ⇒ Object


65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
# File 'lib/alf/relation.rb', line 65

def [](*args)
  attrs = args.map{|arg| arg.is_a?(Hash) ? arg.keys : arg }.flatten
  handler = ->(v){ v.is_a?(Symbol) ? ->{ __send__(v) } : v }
  extension = args.each_with_object({}) do |arg, ext|
    case arg
    when Symbol
      ext[arg] = handler[arg]
    when Hash
      arg.each_pair do |k,v|
        ext[k] = handler[v]
      end
    end
  end
  self.extend(extension).project(attrs)
end

#check_internal_representation!Object


54
55
56
57
58
59
# File 'lib/alf/relation.rb', line 54

def check_internal_representation!
  error = lambda{|msg| raise TypeError, msg }
  error["Set expected"]        unless reused_instance.is_a?(Set)
  error["Superclass mismatch"] unless self.class.superclass == Relation
  self
end

#headingObject

Returns the relation heading


82
83
84
# File 'lib/alf/relation.rb', line 82

def heading
  self.class.heading
end

#keysObject

Returns the relation keys


87
88
89
# File 'lib/alf/relation.rb', line 87

def keys
  Keys[to_attr_list]
end

#to_attr_listObject

Returns the attribute list.


92
93
94
# File 'lib/alf/relation.rb', line 92

def to_attr_list
  heading.to_attr_list
end

#to_cog(plan = nil) ⇒ Object

Returns an engine Cog


107
108
109
# File 'lib/alf/relation.rb', line 107

def to_cog(plan = nil)
  Engine::Leaf.new(self, self)
end

#to_hash(from, to = nil) ⇒ Object


111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
# File 'lib/alf/relation.rb', line 111

def to_hash(from, to=nil)
  if from.is_a?(Hash) and to.nil?
    raise ArgumentError "Hash of size 1 expected." unless from.size==1
    to_hash(from.keys.first, from.values.first)
  else
    from, to = Selection.coerce(from), Selection.coerce(to)
    each.each_with_object({}) do |tuple, hash|
      key, value = from.select(tuple), to.select(tuple)
      if hash.has_key?(key) and hash[key] != value
        raise "Key expected for `#{from}`, divergence found on `#{key}`"
      else
        hash[key] = value
      end
    end
  end
end

#to_relationObject

Returns self


97
98
99
# File 'lib/alf/relation.rb', line 97

def to_relation
  self
end

#to_relvarObject

Returns a ReadOnly relvar


102
103
104
# File 'lib/alf/relation.rb', line 102

def to_relvar
  Relvar::ReadOnly.new(self)
end

#to_ruby_literalObject Also known as: inspect

Returns a literal representation of this relation


134
135
136
# File 'lib/alf/relation.rb', line 134

def to_ruby_literal
  "Alf::Relation([" + tuples.map{|t| Support.to_ruby_literal(t) }.join(', ') + "])"
end

#to_sObject

Returns a textual representation of this relation


129
130
131
# File 'lib/alf/relation.rb', line 129

def to_s
  to_text
end