class Axiom::Relation::Gateway

A relation backed by an adapter

Constants

DECORATED_CLASS

Attributes

adapter[R]

The adapter the gateway will use to fetch results

@return [Adapter::DataObjects]

@api private

relation[R]

The relation the gateway will use to generate SQL

@return [Relation]

@api private

Public Class Methods

new(adapter, relation) click to toggle source

Initialize a Gateway

@param [Adapter::DataObjects] adapter

@param [Relation] relation

@return [undefined]

@api private

# File lib/axiom/relation/gateway.rb, line 40
def initialize(adapter, relation)
  @adapter  = adapter
  @relation = relation
end

Public Instance Methods

difference(other) click to toggle source

Return the diferrence between relations

@example

difference = gateway.difference(other)

@param [Relation] other

the other relation to find the difference with

@return [Gateway]

return a gateway if the adapters are equal

@return [Algebra::Difference]

return a normal dfference when the adapters are not equal

@api public

# File lib/axiom/relation/gateway.rb, line 170
def difference(other)
  binary_operation(__method__, other, Algebra::Difference)
end
each() { |tuple| ... } click to toggle source

Iterate over each row in the results

@example

gateway = Gateway.new(adapter, relation)
gateway.each { |tuple| ... }

@yield [tuple]

@yieldparam [Tuple] tuple

each tuple in the results

@return [self]

@api public

# File lib/axiom/relation/gateway.rb, line 59
def each
  return to_enum unless block_given?
  tuples.each { |tuple| yield tuple }
  self
end
intersect(other) click to toggle source

Return the intersection between relations

@example

intersect = gateway.intersect(other)

@param [Relation] other

the other relation to find the intersect with

@return [Gateway]

return a gateway if the adapters are equal

@return [Algebra::Intersection]

return a normal intersection when the adapters are not equal

@api public

# File lib/axiom/relation/gateway.rb, line 152
def intersect(other)
  binary_operation(__method__, other, Algebra::Intersection)
end
join(other) click to toggle source

Return a relation that is the join of two relations

@example natural join

join = relation.join(other)

@example theta-join using a block

join = relation.join(other) { |r| r.a.gte(r.b) }

@param [Relation] other

the other relation to join

@yield [relation]

optional block to restrict the tuples with

@yieldparam [Relation] relation

the context to evaluate the restriction with

@yieldreturn [Function, call]

predicate to restrict the tuples with

@return [Gateway]

return a gateway if the adapters are equal

@return [Algebra::Join]

return a normal join when the adapters are not equal

@return [Algebra::Restriction]

return a normal restriction when the adapters are not equal
for a theta-join

@api public

Calls superclass method
# File lib/axiom/relation/gateway.rb, line 94
def join(other)
  if block_given?
    super
  else
    binary_operation(__method__, other, Algebra::Join)
  end
end
product(other) click to toggle source

Return a relation that is the cartesian product of two relations

@example

product = gateway.product(other)

@param [Relation] other

the other relation to find the product with

@return [Gateway]

return a gateway if the adapters are equal

@return [Algebra::Product]

return a normal product when the adapters are not equal

@api public

# File lib/axiom/relation/gateway.rb, line 116
def product(other)
  binary_operation(__method__, other, Algebra::Product)
end
respond_to?(method, *) click to toggle source

Test if the method is supported on this object

@param [Symbol] method

@return [Boolean]

@api private

Calls superclass method
# File lib/axiom/relation/gateway.rb, line 225
def respond_to?(method, *)
  super || forwardable?(method)
end
summarize(summarize_with = TABLE_DEE, &block) click to toggle source

Return a summarized relation

@example with no arguments

summarization = gateway.summarize do |context|
  context.add(:count, context[:id].count)
end

@example with a relation

summarization = gateway.summarize(relation) do |context|
  context.add(:count, context[:id].count)
end

@example with a header

summarization = gateway.summarize([:name]) do |context|
  context.add(:count, context[:id].count)
end

@example with another gateway

summarization = gateway.summarize(other_gateway) do |context|
  context.add(:count, context[:id].count)
end

@param [Gateway, Relation, Header, to_ary] summarize_with

@yield [function]

Evaluate a summarization function

@yieldparam [Evaluator::Context] context

the context to evaluate the function within

@return [Gateway]

return a gateway if the adapters are equal, or there is no adapter

@return [Algebra::Summarization]

return a normal summarization when the adapters are not equal

@api public

# File lib/axiom/relation/gateway.rb, line 210
def summarize(summarize_with = TABLE_DEE, &block)
  if summarize_merge?(summarize_with)
    summarize_merge(summarize_with, &block)
  else
    summarize_split(summarize_with, &block)
  end
end
union(other) click to toggle source

Return the union between relations

@example

union = gateway.union(other)

@param [Relation] other

the other relation to find the union with

@return [Gateway]

return a gateway if the adapters are equal

@return [Algebra::Union]

return a normal union when the adapters are not equal

@api public

# File lib/axiom/relation/gateway.rb, line 134
def union(other)
  binary_operation(__method__, other, Algebra::Union)
end

Private Instance Methods

binary_operation(method, other, factory) click to toggle source

Return a binary relation

@param [Relation] other

@return [Gateway]

return a gateway if the adapters are equal

@return [Relation]

return a binary relation when the adapters are not equal

@api private

# File lib/axiom/relation/gateway.rb, line 304
def binary_operation(method, other, factory)
  if same_adapter?(other)
    forward(method, other.relation)
  else
    factory.new(self, other)
  end
end
forward(*args, &block) click to toggle source

Forward the message to the relation

@param [Array] args

@return [self]

return self for all command methods

@return [Object]

return response from all query methods

@api private

# File lib/axiom/relation/gateway.rb, line 268
def forward(*args, &block)
  relation = self.relation
  response = relation.public_send(*args, &block)
  if response.equal?(relation)
    self
  elsif response.kind_of?(DECORATED_CLASS)
    self.class.new(adapter, response)
  else
    response
  end
end
forwardable?(method) click to toggle source

Test if the method can be forwarded to the relation

@param [Symbol] method

@return [Boolean]

@api private

# File lib/axiom/relation/gateway.rb, line 254
def forwardable?(method)
  relation.respond_to?(method)
end
gateway?(other) click to toggle source

Test if the other object is a Gateway

@param [Gateway, Relation] other

@return [Boolean]

@api private

# File lib/axiom/relation/gateway.rb, line 319
def gateway?(other)
  other.kind_of?(Gateway)
end
method_missing(method, *args, &block) click to toggle source

Proxy the message to the relation

@param [Symbol] method

@param [Array] args

@return [self]

return self for all command methods

@return [Object]

return response from all query methods

@api private

Calls superclass method
# File lib/axiom/relation/gateway.rb, line 243
def method_missing(method, *args, &block)
  forwardable?(method) ? forward(method, *args, &block) : super
end
same_adapter?(other) click to toggle source

Test if the other object uses the same adapter

@param [Gateway, Relation] other

@return [Boolean]

@api private

# File lib/axiom/relation/gateway.rb, line 330
def same_adapter?(other)
  gateway?(other) && adapter.eql?(other.adapter)
end
summarize_merge(summarize_with, &block) click to toggle source

Merge the summarize_with into the summarization

@param [Gateway, Relation, Header] summarize_with

@return [Gateway]

@api private

# File lib/axiom/relation/gateway.rb, line 354
def summarize_merge(summarize_with, &block)
  summarize_with = summarize_with.relation if gateway?(summarize_with)
  forward(:summarize, summarize_with, &block)
end
summarize_merge?(summarize_with) click to toggle source

Test if the summarize_with object can be merged into the summarization

@param [Gateway, Relation, Header] summarize_with

@return [Boolean]

@api private

# File lib/axiom/relation/gateway.rb, line 341
def summarize_merge?(summarize_with)
  !summarize_with.respond_to?(:header) ||
  summarize_with.equal?(TABLE_DEE)     ||
  same_adapter?(summarize_with)
end
summarize_split(summarize_with, &block) click to toggle source

Split the summarize_with into a separate relation, wrapped in a summarization

@param [Gateway, Relation, Header] summarize_with

@return [Algebra::Summarization]

@api private

# File lib/axiom/relation/gateway.rb, line 366
def summarize_split(summarize_with, &block)
  # evaluate the gateway, then summarize with the provided relation
  context = Evaluator::Context.new(header - summarize_with.header, &block)
  Algebra::Summarization.new(self, summarize_with, context.functions)
end
tuples() click to toggle source

Return a list of tuples to iterate over

@return [#each]

@api private

# File lib/axiom/relation/gateway.rb, line 285
def tuples
  relation = self.relation
  if materialized?
    relation
  else
    DECORATED_CLASS.new(header, adapter.read(relation))
  end
end