lib/lotus/model.rb in lotus-model-0.1.2 vs lib/lotus/model.rb in lotus-model-0.2.0
- old
+ new
@@ -1,28 +1,189 @@
require 'lotus/model/version'
require 'lotus/entity'
require 'lotus/repository'
require 'lotus/model/mapper'
+require 'lotus/model/configuration'
module Lotus
# Model
#
# @since 0.1.0
module Model
- # Error for not found entity
- #
- # @since 0.1.0
- #
- # @see Lotus::Repository.find
- class EntityNotFound < ::StandardError
- end
-
# Error for non persisted entity
# It's raised when we try to update or delete a non persisted entity.
#
# @since 0.1.0
#
# @see Lotus::Repository.update
class NonPersistedEntityError < ::StandardError
end
+
+ # Error for invalid mapper configuration
+ # It's raised when mapping is not configured correctly
+ #
+ # @since 0.2.0
+ #
+ # @see Lotus::Configuration#mapping
+ class InvalidMappingError < ::StandardError
+ end
+
+ include Utils::ClassAttribute
+
+ # Framework configuration
+ #
+ # @since 0.2.0
+ # @api private
+ class_attribute :configuration
+ self.configuration = Configuration.new
+
+ # Configure the framework.
+ # It yields the given block in the context of the configuration
+ #
+ # @param blk [Proc] the configuration block
+ #
+ # @since 0.2.0
+ #
+ # @see Lotus::Model
+ #
+ # @example
+ # require 'lotus/model'
+ #
+ # Lotus::Model.configure do
+ # adapter type: :sql, uri: 'postgres://localhost/database'
+ #
+ # mapping do
+ # collection :users do
+ # entity User
+ #
+ # attribute :id, Integer
+ # attribute :name, String
+ # end
+ # end
+ # end
+ #
+ # Adapter MUST follow the convention in which adapter class is inflection of adapter name
+ # The above example has name :sql, thus derived class will be `Lotus::Model::Adapters::SqlAdapter`
+ def self.configure(&blk)
+ configuration.instance_eval(&blk)
+ self
+ end
+
+ # Load the framework
+ #
+ # @since 0.2.0
+ # @api private
+ def self.load!
+ configuration.load!
+ end
+
+ # Unload the framework
+ #
+ # @since 0.2.0
+ # @api private
+ def self.unload!
+ configuration.unload!
+ end
+
+ # Duplicate Lotus::Model in order to create a new separated instance
+ # of the framework.
+ #
+ # The new instance of the framework will be completely decoupled from the
+ # original. It will inherit the configuration, but all the changes that
+ # happen after the duplication, won't be reflected on the other copies.
+ #
+ # @return [Module] a copy of Lotus::Model
+ #
+ # @since 0.2.0
+ # @api private
+ #
+ # @example Basic usage
+ # require 'lotus/model'
+ #
+ # module MyApp
+ # Model = Lotus::Model.dupe
+ # end
+ #
+ # MyApp::Model == Lotus::Model # => false
+ #
+ # MyApp::Model.configuration ==
+ # Lotus::Model.configuration # => false
+ #
+ # @example Inheriting configuration
+ # require 'lotus/model'
+ #
+ # Lotus::Model.configure do
+ # adapter type: :sql, uri: 'sqlite3://uri'
+ # end
+ #
+ # module MyApp
+ # Model = Lotus::Model.dupe
+ # end
+ #
+ # module MyApi
+ # Model = Lotus::Model.dupe
+ # Model.configure do
+ # adapter type: :sql, uri: 'postgresql://uri'
+ # end
+ # end
+ #
+ # Lotus::Model.configuration.adapter_config.uri # => 'sqlite3://uri'
+ # MyApp::Model.configuration.adapter_config.uri # => 'sqlite3://uri'
+ # MyApi::Model.configuration.adapter_config.uri # => 'postgresql://uri'
+ def self.dupe
+ dup.tap do |duplicated|
+ duplicated.configuration = configuration.duplicate
+ end
+ end
+
+ # Duplicate the framework and generate modules for the target application
+ #
+ # @param mod [Module] the Ruby namespace of the application
+ # @param blk [Proc] an optional block to configure the framework
+ #
+ # @return [Module] a copy of Lotus::Model
+ #
+ # @since 0.2.0
+ #
+ # @see Lotus::Model#dupe
+ # @see Lotus::Model::Configuration
+ #
+ # @example Basic usage
+ # require 'lotus/model'
+ #
+ # module MyApp
+ # Model = Lotus::Model.dupe
+ # end
+ #
+ # # It will:
+ # #
+ # # 1. Generate MyApp::Model
+ # # 2. Generate MyApp::Entity
+ # # 3. Generate MyApp::Repository
+ #
+ # MyApp::Model == Lotus::Model # => false
+ # MyApp::Repository == Lotus::Repository # => false
+ #
+ # @example Block usage
+ # require 'lotus/model'
+ #
+ # module MyApp
+ # Model = Lotus::Model.duplicate(self) do
+ # adapter type: :memory, uri: 'memory://localhost'
+ # end
+ # end
+ #
+ # Lotus::Model.configuration.adapter_config # => nil
+ # MyApp::Model.configuration.adapter_config # => #<Lotus::Model::Config::Adapter:0x007ff0ff0244f8 @type=:memory, @uri="memory://localhost", @class_name="MemoryAdapter">
+ def self.duplicate(mod, &blk)
+ dupe.tap do |duplicated|
+ mod.module_eval %{
+ Entity = Lotus::Entity.dup
+ Repository = Lotus::Repository.dup
+ }
+
+ duplicated.configure(&blk) if block_given?
+ end
+ end
+
end
end