lib/rom/relation.rb in rom-1.0.0 vs lib/rom/relation.rb in rom-2.0.0
- old
+ new
@@ -6,11 +6,15 @@
require 'rom/relation/loaded'
require 'rom/relation/curried'
require 'rom/relation/composite'
require 'rom/relation/graph'
require 'rom/relation/materializable'
+require 'rom/association_set'
+require 'rom/types'
+require 'rom/schema'
+
module ROM
# Base relation class
#
# Relation is a proxy for the dataset object provided by the gateway. It
# forwards every method to the dataset, which is why the "native" interface of
@@ -30,83 +34,139 @@
include Options
include Dry::Equalizer(:dataset)
include Materializable
include Pipeline
+ # @!attribute [r] mappers
+ # @return [MapperRegistry] an optional mapper registry (empty by default)
option :mappers, reader: true, default: proc { MapperRegistry.new }
- # Dataset used by the relation
+ # @!attribute [r] schema_hash
+ # @return [Object#[]] tuple processing function, uses schema or defaults to Hash[]
+ # @api private
+ option :schema_hash, reader: true, default: -> relation {
+ relation.schema? ? Types::Coercible::Hash.schema(relation.schema.to_h) : Hash
+ }
+
+ # @!attribute [r] associations
+ # @return [AssociationSet] Schema's association set (empty by default)
+ option :associations, reader: true, default: -> rel {
+ rel.schema? ? rel.schema.associations : Schema::EMPTY_ASSOCIATION_SET
+ }
+
+ # @!attribute [r] dataset
+ # @return [Object] dataset used by the relation provided by relation's gateway
+ # @api public
+ attr_reader :dataset
+
+ # @!attribute [r] schema
+ # @return [Schema] returns relation schema object (if defined)
+ # @api public
+ attr_reader :schema
+
+ # Initializes a relation object
#
- # This object is provided by the gateway during the setup
+ # @param dataset [Object]
#
- # @return [Object]
+ # @param options [Hash]
+ # @option :mappers [MapperRegistry]
+ # @option :schema_hash [#[]]
+ # @option :associations [AssociationSet]
#
- # @api private
- attr_reader :dataset
-
- # @api private
+ # @api public
def initialize(dataset, options = EMPTY_HASH)
@dataset = dataset
+ @schema = self.class.schema
super
end
- # Yield dataset tuples
+ # Yields relation tuples
#
# @yield [Hash]
+ # @return [Enumerator] if block is not provided
#
- # @api private
+ # @api public
def each(&block)
return to_enum unless block
dataset.each { |tuple| yield(tuple) }
end
- # Eager load other relation(s) for this relation
+ # Composes with other relations
#
- # @param [Array<Relation>] others The other relation(s) to eager load
+ # @param *others [Array<Relation>] The other relation(s) to compose with
#
# @return [Relation::Graph]
#
# @api public
def combine(*others)
Graph.build(self, others)
end
- # Load relation
+ # Loads relation
#
# @return [Relation::Loaded]
#
# @api public
def call
Loaded.new(self)
end
- # Materialize a relation into an array
+ # Materializes a relation into an array
#
# @return [Array<Hash>]
#
# @api public
def to_a
to_enum.to_a
end
- # Return if this relation is curried
+ # Returns if this relation is curried
#
# @return [false]
#
# @api private
def curried?
false
end
+ # Returns if this relation is a graph
+ #
+ # @return [false]
+ #
# @api private
- def with(options)
- __new__(dataset, options)
+ def graph?
+ false
end
+ # Returns true if a relation has schema defined
+ #
+ # @return [TrueClass, FalseClass]
+ #
+ # @api private
+ def schema?
+ ! schema.nil?
+ end
+
+ # Returns a new instance with the same dataset but new options
+ #
+ # @param new_options [Hash]
+ #
+ # @return [Relation]
+ #
+ # @api private
+ def with(new_options)
+ __new__(dataset, options.merge(new_options))
+ end
+
private
# @api private
def __new__(dataset, new_opts = EMPTY_HASH)
self.class.new(dataset, options.merge(new_opts))
+ end
+
+ # @api private
+ def composite_class
+ Relation::Composite
end
end
end