lib/hanami/model.rb in hanami-model-0.0.0 vs lib/hanami/model.rb in hanami-model-0.6.0

- old
+ new

@@ -1,7 +1,209 @@ -require "hanami/model/version" +require 'hanami/model/version' +require 'hanami/entity' +require 'hanami/entity/dirty_tracking' +require 'hanami/repository' +require 'hanami/model/mapper' +require 'hanami/model/configuration' +require 'hanami/model/error' module Hanami + # Model + # + # @since 0.1.0 module Model - # Your code goes here... + # Error for non persisted entity + # It's raised when we try to update or delete a non persisted entity. + # + # @since 0.1.0 + # + # @see Hanami::Repository.update + class NonPersistedEntityError < Hanami::Model::Error + end + + # Error for invalid mapper configuration + # It's raised when mapping is not configured correctly + # + # @since 0.2.0 + # + # @see Hanami::Configuration#mapping + class InvalidMappingError < Hanami::Model::Error + end + + # Error for invalid raw command syntax + # + # @since 0.5.0 + class InvalidCommandError < Hanami::Model::Error + def initialize(message = "Invalid command") + super + end + end + + # Error for invalid raw query syntax + # + # @since 0.3.1 + class InvalidQueryError < Hanami::Model::Error + def initialize(message = "Invalid query") + super + end + 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 Hanami::Model + # + # @example + # require 'hanami/model' + # + # Hanami::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 `Hanami::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 Hanami::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 Hanami::Model + # + # @since 0.2.0 + # @api private + # + # @example Basic usage + # require 'hanami/model' + # + # module MyApp + # Model = Hanami::Model.dupe + # end + # + # MyApp::Model == Hanami::Model # => false + # + # MyApp::Model.configuration == + # Hanami::Model.configuration # => false + # + # @example Inheriting configuration + # require 'hanami/model' + # + # Hanami::Model.configure do + # adapter type: :sql, uri: 'sqlite3://uri' + # end + # + # module MyApp + # Model = Hanami::Model.dupe + # end + # + # module MyApi + # Model = Hanami::Model.dupe + # Model.configure do + # adapter type: :sql, uri: 'postgresql://uri' + # end + # end + # + # Hanami::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.new + 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 Hanami::Model + # + # @since 0.2.0 + # + # @see Hanami::Model#dupe + # @see Hanami::Model::Configuration + # + # @example Basic usage + # require 'hanami/model' + # + # module MyApp + # Model = Hanami::Model.dupe + # end + # + # # It will: + # # + # # 1. Generate MyApp::Model + # # 2. Generate MyApp::Entity + # # 3. Generate MyApp::Repository + # + # MyApp::Model == Hanami::Model # => false + # MyApp::Repository == Hanami::Repository # => false + # + # @example Block usage + # require 'hanami/model' + # + # module MyApp + # Model = Hanami::Model.duplicate(self) do + # adapter type: :memory, uri: 'memory://localhost' + # end + # end + # + # Hanami::Model.configuration.adapter_config # => nil + # MyApp::Model.configuration.adapter_config # => #<Hanami::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 = Hanami::Entity.dup + Repository = Hanami::Repository.dup + } + + duplicated.configure(&blk) if block_given? + end + end + end end