class Axiom::Algebra::Projection

Specify only specific attributes to keep in the relation

Public Class Methods

new(operand, attributes) click to toggle source

Initialize a Projection

@param [Relation] operand

the relation to project

@param [#to_ary] attributes

the attributes to keep in the header

@return [undefined]

@api private

Calls superclass method Axiom::Relation::Operation::Unary::new
# File lib/axiom/algebra/projection.rb, line 21
def initialize(operand, attributes)
  super(operand)
  @header = @header.project(attributes)
end

Public Instance Methods

delete(other) click to toggle source

Delete a relation from the Projection

@example

new_relation = projection.delete(other)

@param [Relation] other

@return [Projection]

@raise [InvalidHeaderError]

raised if the headers are not equivalent

@api public

# File lib/axiom/algebra/projection.rb, line 86
def delete(other)
  other = coerce(other)
  assert_equivalent_headers(other)
  operand.delete(extend_other(other)).project(header)
end
each() { |seen = tuple| ... } click to toggle source

Iterate over each tuple in the set

@example

projection = Projection.new(operand, attributes)
projection.each { |tuple| ... }

@yield [tuple]

@yieldparam [Tuple] tuple

each tuple in the set

@return [self]

@api public

# File lib/axiom/algebra/projection.rb, line 40
def each
  return to_enum unless block_given?
  seen = {}
  operand.each do |tuple|
    tuple = tuple.project(header)
    yield seen[tuple] = tuple unless seen.key?(tuple)
  end
  self
end
insert(other) click to toggle source

Insert a relation into the Projection

@example

new_relation = projection.insert(other)

@param [Relation] other

@return [Projection]

@raise [RequiredAttributesError]

raised when inserting into a relation with required attributes removed

@raise [InvalidHeaderError]

raised if the headers are not equivalent

@api public

# File lib/axiom/algebra/projection.rb, line 66
def insert(other)
  other = coerce(other)
  assert_removed_attributes_optional
  assert_equivalent_headers(other)
  operand.insert(extend_other(other)).project(header)
end

Private Instance Methods

assert_equivalent_headers(other) click to toggle source

Assert that other relation header is equivalent

@param [Relation] other

@return [undefined]

@raise [InvalidHeaderError]

raised if the headers are not equivalent

@api private

# File lib/axiom/algebra/projection.rb, line 119
def assert_equivalent_headers(other)
  if header != other.header
    fail InvalidHeaderError, 'the headers must be equivalent'
  end
end
assert_removed_attributes_optional() click to toggle source

Assert that removed attributes are optional

@return [undefined]

@raise [RequiredAttributesError]

raised when inserting into a relation with required attributes removed

@api private

# File lib/axiom/algebra/projection.rb, line 102
def assert_removed_attributes_optional
  names = required_attribute_names
  if names.any?
    fail RequiredAttributesError, "required attributes #{names} have been removed"
  end
end
extend_other(other) click to toggle source

Extend the other relation with removed attributes

@param [Relation] other

@return [Extension]

@api private

# File lib/axiom/algebra/projection.rb, line 152
def extend_other(other)
  other.extend(Hash[removed_attributes.zip])
end
removed_attributes() click to toggle source

Attributes that were removed by the projection

@return [Array<Attribute>]

@api private

# File lib/axiom/algebra/projection.rb, line 141
def removed_attributes
  operand.header - header
end
required_attribute_names() click to toggle source

Names of the required attributes that were removed

@return [Array<Symbol>]

@api private

# File lib/axiom/algebra/projection.rb, line 130
def required_attribute_names
  removed_attributes.each_with_object([]) do |attribute, names|
    names << attribute.name if attribute.required?
  end
end