lib/dm-core/repository.rb
module DataMapper
class Repository
include DataMapper::Assertions
extend Equalizer
equalize :name
# Get the list of adapters registered for all Repositories,
# keyed by repository name.
#
# TODO: create example
#
# @return [Hash(Symbol => Adapters::AbstractAdapter)]
# the adapters registered for all Repositories
#
# @api private
def self.adapters
@adapters ||= {}
end
# Get the stack of current repository contexts
#
# TODO: create example
#
# @return [Array]
# List of Repository contexts for the current Thread
#
# @api private
def self.context
Thread.current[:dm_repository_contexts] ||= []
end
# Get the default name of this Repository
#
# TODO: create example
#
# @return [Symbol]
# the default name of this repository
#
# @api private
def self.default_name
:default
end
# @api semipublic
attr_reader :name
# @api semipublic
alias_method :to_sym, :name
# Get the adapter for this repository
#
# Lazy loads adapter setup from registered adapters
#
# TODO: create example
#
# @return [Adapters::AbstractAdapter]
# the adapter for this repository
#
# @raise [RepositoryNotSetupError]
# if there is no adapter registered for a repository named @name
#
# @api semipublic
def adapter
# Make adapter instantiation lazy so we can defer repository setup until it's actually
# needed. Do not remove this code.
@adapter ||=
begin
adapters = self.class.adapters
unless adapters.key?(@name)
raise RepositoryNotSetupError, "Adapter not set: #{@name}. Did you forget to setup?"
end
adapters[@name]
end
end
# Get the identity for a particular model within this repository.
#
# If one doesn't yet exist, create a new default in-memory IdentityMap
# for the requested model.
#
# TODO: create example
#
# @param [Model] model
# Model whose identity map should be returned
#
# @return [IdentityMap]
# The IdentityMap for model in this Repository
#
# @api private
def identity_map(model)
@identity_maps[model.base_model] ||= IdentityMap.new
end
# Executes a block in the scope of this Repository
#
# TODO: create example
#
# @yieldparam [Repository] repository
# yields self within the block
#
# @yield
# execute block in the scope of this Repository
#
# @api private
def scope
context = Repository.context
context << self
begin
yield self
ensure
context.pop
end
end
# Create a Query or subclass instance for this repository.
#
# @param [Model] model
# the Model to retrieve results from
# @param [Hash] options
# the conditions and scope
#
# @return [Query]
#
# @api semipublic
def new_query(model, options = {})
adapter.new_query(self, model, options)
end
# Create one or more resource instances in this repository.
#
# TODO: create example
#
# @param [Enumerable(Resource)] resources
# The list of resources (model instances) to create
#
# @return [Integer]
# The number of records that were actually saved into the data-store
#
# @api semipublic
def create(resources)
adapter.create(resources)
end
# Retrieve a collection of results of a query
#
# TODO: create example
#
# @param [Query] query
# composition of the query to perform
#
# @return [Array]
# result set of the query
#
# @api semipublic
def read(query)
return [] unless query.valid?
query.model.load(adapter.read(query), query)
end
# Update the attributes of one or more resource instances
#
# TODO: create example
#
# @param [Hash(Property => Object)] attributes
# hash of attribute values to set, keyed by Property
# @param [Collection] collection
# collection of records to be updated
#
# @return [Integer]
# the number of records updated
#
# @api semipublic
def update(attributes, collection)
return 0 unless collection.query.valid? && attributes.any?
adapter.update(attributes, collection)
end
# Delete one or more resource instances
#
# TODO: create example
#
# @param [Collection] collection
# collection of records to be deleted
#
# @return [Integer]
# the number of records deleted
#
# @api semipublic
def delete(collection)
return 0 unless collection.query.valid?
adapter.delete(collection)
end
# Return a human readable representation of the repository
#
# TODO: create example
#
# @return [String]
# human readable representation of the repository
#
# @api private
def inspect
"#<#{self.class.name} @name=#{@name}>"
end
private
# Initializes a new Repository
#
# TODO: create example
#
# @param [Symbol] name
# The name of the Repository
#
# @api semipublic
def initialize(name)
@name = name.to_sym
@identity_maps = {}
end
end # class Repository
end # module DataMapper