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