# frozen_string_literal: true require "dry/container" module ROM # ROM container is an isolated environment with no global state where all # components are registered. Container objects provide access to your # relations, commands and mappers. ROM containers are usually configured and # handled via framework integrations, although it is easy to use them # standalone. # # There are 3 types of container setup: # # * Setup DSL - a simple block-based configuration which allows configuring # all components and gives you back a container instance. This type is suitable # for small scripts, or in some cases rake tasks # * Explicit setup - this type requires creating a configuration object, # registering component classes (ie relation classes) and passing the config # to container builder function. This type is suitable when your environment # is not typical and you need full control over component registration # * Explicit setup with auto-registration - same as explicit setup but allows # you to configure auto-registration mechanism which will register component # classes for you, based on dir/file naming conventions. This is the most # common type of setup that's used by framework integrations # # @example in-line setup # rom = ROM.setup(:sql, 'sqlite::memory') do |config| # config.default.create_table :users do # primary_key :id # column :name, String, null: false # end # # config.relation(:users) do # schema(infer: true) # # def by_name(name) # where(name: name) # end # end # end # # rom.relations[:users].insert(name: "Jane") # # rom.relations[:users].by_name("Jane").to_a # # [{:id=>1, :name=>"Jane"}] # # @example multi-step setup with explicit component classes # config = ROM::Configuration.new(:sql, 'sqlite::memory') # # config.default.create_table :users do # primary_key :id # column :name, String, null: false # end # # class Users < ROM::Relation[:sql] # schema(:users, infer: true) # # def by_name(name) # where(name: name) # end # end # # config.register_relation(Users) # # rom = ROM.setup(config) # # rom.relations[:users].insert(name: "Jane") # # rom.relations[:users].by_name("Jane").to_a # # [{:id=>1, :name=>"Jane"}] # # # @example multi-step setup with auto-registration # config = ROM::Configuration.new(:sql, 'sqlite::memory') # config.auto_register('./persistence', namespace: false) # # config.default.create_table :users do # primary_key :id # column :name, String, null: false # end # # # ./persistence/relations/users.rb # class Users < ROM::Relation[:sql] # schema(infer: true) # # def by_name(name) # where(name: name) # end # end # # rom = ROM.setup(config) # # rom.relations[:users].insert(name: "Jane") # # rom.relations[:users].by_name("Jane").to_a # # [{:id=>1, :name=>"Jane"}] # # @api public class Container include Dry::Container::Mixin include Dry::Equalizer(:gateways, :relations, :mappers, :commands) # @api private def self.new(configuration) super().tap do |container| container.register(:configuration, memoize: true) do Setup::Configuration.new( configuration: configuration, container: container ) end end end # Return runtime configuration with component registries # # @return [Setup::Configuration] # # @api public def configuration self[:configuration] end # Return registered gateways # # @return [HashGateway>] # # @api public def gateways configuration.gateways end # Return relation registry # # @return [RelationRegistry] # # @api public def schemas configuration.schemas end # Return relation registry # # @return [RelationRegistry] # # @api public def relations configuration.relations end # Return mapper registry for all relations # # @return [HashMapperRegistry] # # @api public def mappers configuration.mappers end # Return command registry # # @return [HashCommandRegistry] # # @api public def commands configuration.commands end # Disconnect all gateways # # @example # rom = ROM.setup(:sql, 'sqlite://my_db.sqlite') # rom.relations[:users].insert(name: "Jane") # rom.disconnect # # @return [HashGateway>] a hash with disconnected gateways # # @api public def disconnect gateways.each_value(&:disconnect) end end end