class Axiom::Relation::Keys

A set of keys in a Header

Constants

EMPTY

Represent an empty set of keys

Public Class Methods

coerce(object, &block) click to toggle source

Coerce an Array-like object into Keys

@param [Keys, to_ary] object

@yield [attributes]

@yieldparam [Header, Array] attributes

the attributes in each key

@return [Keys]

@api private

# File lib/axiom/relation/keys.rb, line 30
def self.coerce(object, &block)
  if object.kind_of?(self)
    object
  else
    block ||= method(:coerce_attributes)
    new(object.map(&block))
  end
end
new(keys = EMPTY_ARRAY) click to toggle source

Instantiate Keys

@example

keys = Keys.new(keys)

@param [Array<Header>] keys

@return [Keys]

@api public

Calls superclass method
# File lib/axiom/relation/keys.rb, line 49
def self.new(keys = EMPTY_ARRAY)
  assert_irreducible_keys(keys.map(&:to_set))
  super
end
new(keys) click to toggle source

Initialize Keys

@example

keys = Keys.new([[:id]])

@param [Array<Header>] keys

@return [undefined]

@api public

# File lib/axiom/relation/keys.rb, line 111
def initialize(keys)
  @keys = self.class.freezer.call(keys)
end

Private Class Methods

assert_irreducible_keys(keys) click to toggle source

Assert the keys are irreducible

In a relation a candidate key must be irreducible, which means that there can’t exist another key that is a proper subset of it. If this occurs, we should raise an exception because it means there is a specification error in the system.

@param [Array<Set>] keys

@return [undefined]

@raise [ReducibleKeyError]

raised if a key can be reduced

@api private

# File lib/axiom/relation/keys.rb, line 80
def self.assert_irreducible_keys(keys)
  reducible_keys = reducible_keys(keys)
  if reducible_keys
    fail ReducibleKeyError, "reducible keys: #{reducible_keys}"
  end
end
coerce_attributes(attributes) click to toggle source

Coerce the attributes into a Header

@param [Object] attributes

@return [Header]

@api private

# File lib/axiom/relation/keys.rb, line 61
def self.coerce_attributes(attributes)
  Header.coerce(attributes)
end
reducible_keys(keys) click to toggle source

The keys that can be reduced

@param [Array<Header>] keys

@return [Boolean]

@api private

# File lib/axiom/relation/keys.rb, line 94
def self.reducible_keys(keys)
  keys.permutation(2).select { |key, other| key.proper_superset?(other) }
    .transpose.first
end

Public Instance Methods

difference(other) click to toggle source

Return the difference of the keys with other keys

@example

difference = keys.difference(other)

@param [Keys] other

@return [Keys]

@api public

# File lib/axiom/relation/keys.rb, line 225
def difference(other)
  new(to_ary - other)
end
each() { |key| ... } click to toggle source

Iterate over each key in the Keys

@example

keys = Keys.new(keys)
keys.each { |key| ... }

@yield [key]

@yieldparam [Header] key

@return [self]

@api public

# File lib/axiom/relation/keys.rb, line 128
def each
  return to_enum unless block_given?
  to_ary.each { |key| yield key }
  self
end
empty?() click to toggle source

Test if there are no keys

@example

keys.empty?  # => true or false

@return [Boolean]

@api public

# File lib/axiom/relation/keys.rb, line 249
def empty?
  to_ary.empty?
end
extend(attributes) click to toggle source

Return keys with the new attributes added

@example

extended = keys.extend(attributes)

@param [#to_ary] attributes

the attributes to add to the keys

@return [Keys]

@api public

# File lib/axiom/relation/keys.rb, line 164
def extend(attributes)
  if empty?
    coerce(attributes)
  else
    new(map { |key| key | attributes })
  end
end
intersect(other) click to toggle source

Return the intersection of the keys with other keys

@example

intersection = keys.intersect(other)

@param [Keys] other

@return [Keys]

@api public

# File lib/axiom/relation/keys.rb, line 197
def intersect(other)
  new(to_ary & other)
end
project(attributes) click to toggle source

Return keys with only the attributes specified

When the attributes do not match any attributes in an existing key, then the key should be removed because it means the attributes it applied against no longer exist in the new header.

@example

projected = keys.project(attributes)

@param [#map] attributes

the attributes to keep in the keys

@return [Keys]

@api public

# File lib/axiom/relation/keys.rb, line 149
def project(attributes)
  new(map { |key| key & attributes }.delete_if(&:empty?))
end
rename(aliases) click to toggle source

Return keys with the attributes renamed

@example

renamed = keys.rename(aliases)

@param [Aliases] aliases

the old and new attribute names

@return [Keys]

@api public

# File lib/axiom/relation/keys.rb, line 183
def rename(aliases)
  new(map { |key| key.rename(aliases) })
end
to_ary() click to toggle source

Convert the Keys into an Array

@example

array = keys.to_ary

@return [Array]

@api public

# File lib/axiom/relation/keys.rb, line 237
def to_ary
  @keys
end
union(other) click to toggle source

Return the union of the keys with other keys

@example

union = keys.union(other)

@param [Keys] other

@return [Keys]

@api public

# File lib/axiom/relation/keys.rb, line 211
def union(other)
  new(to_ary | other)
end

Private Instance Methods

coerce(object) click to toggle source

Coerce the object into Keys

@param [Keys, to_ary] object

@return [Keys]

@api private

# File lib/axiom/relation/keys.rb, line 273
def coerce(object)
  self.class.coerce(object)
end
new(keys) click to toggle source

Utility method to instantiate Keys

@param [Array] keys

@return [Keys]

@api private

# File lib/axiom/relation/keys.rb, line 262
def new(keys)
  to_ary == keys ? self : self.class.new(keys)
end