# frozen_string_literal: true module LunaPark module Extensions # @example # class ProductRepository # include LunaPark::Extensions::DataMapper # # entity Product # mapper ProductMapper # # def find(id) # read_one products.where(id: id) # end # # def all # read_all products # end # # def save(input) # entity = wrap(input) # row = to_row(entity) # new_row = products.where(id: entity.id).update(row) # new_attrs = from_row(new_row) # entity.set_attributes(new_attrs) # entity # end # # private # # # Common dataset method is usefull for extensions # def dataset # SEQUEL_CONNECTION[:products] # end # # alias products dataset # end module DataMapper def self.included(base) base.extend ClassMethods base.include InstanceMethods end module ClassMethods attr_reader :entity_class, :mapper_class # Configure repository def entity(entity_class = nil) @entity_class = entity_class end def mapper(mapper_class = nil) @mapper_class = mapper_class end DEFAULT_PRIMARY_KEY = :id def primary_key(pk = nil) @db_primary_key = pk end def db_primary_key @db_primary_key || DEFAULT_PRIMARY_KEY end end module InstanceMethods def transaction(&block) dataset.transaction(&block) end private # Helpers # Get collection of entities from row # @example # def where_type(type) # read_all products.where(type: type) # end def read_all(rows) to_entities from_rows rows.to_a end # Get one entity from row # @example # def find(id) # read_all products.where(id: id) # end def read_one(row) to_entity from_row row end # Mapper helpers # @example # def create(entities) # rows = to_rows(entities) # database.insert_many(rows) # end def to_rows(input_array) mapper_class ? mapper_class.to_rows(input_array) : input_array.map(&:to_h) end # @example # def create(entity) # row = to_row(entity) # database.insert(row) # end def to_row(input) mapper_class ? mapper_class.to_row(input) : input.to_h end # @example # def where_type(type) # entities_attrs = from_rows(products.where(type: type)) # entities_attrs.map { |entity_attrs| Entity.new(entity_attrs) } # end def from_rows(rows_array) mapper_class ? mapper_class.from_rows(rows_array) : rows_array end # @example # def find(id) # entity_attrs = from_row(products.where(id: id)) # Entity.new(entity_attrs) # end def from_row(input) return if input.nil? raise ArgumentError, 'Can not be an Array' if input.is_a?(Array) mapper_class ? mapper_class.from_row(input.to_h) : input end # Entity construction helpers # @example # to_entities(attributes_hashes) # => Array of Entity # to_entities(attributes_hash) # => Array of Entity def to_entities(attrs_array) Array(attrs_array).map { |attrs| to_entity(attrs) } end # @example # to_entity(attributes_hash) # => Entity def to_entity(attrs) return if attrs.nil? entity_class ? entity_class.new(attrs) : attrs end # Entity wrapping helpers # @example # to_entities(attributes_hashes) # => Array of Entity # to_entities(entities) # => Array of Entity # to_entities(entity) # => Array of Entity def wrap_all(input_array) Array(input_array).map { |input| wrap(input) } end # @example # to_entity(attributes_hash) # => Entity # to_entity(entity) # => Entity def wrap(input) return if input.nil? entity_class ? entity_class.wrap(input) : input end # Read config def mapper_class self.class.mapper_class end def entity_class self.class.entity_class end def primary_key self.class.db_primary_key end # Factory Methods # Usefull for extensions def dataset raise NotImplementedError end end end end end