rom 2.0.2 → 3.0.0.beta1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.travis.yml +4 -4
- data/CHANGELOG.md +34 -1
- data/Gemfile +16 -2
- data/Rakefile +7 -2
- data/lib/rom/array_dataset.rb +44 -0
- data/lib/rom/association_set.rb +11 -5
- data/lib/rom/auto_curry.rb +55 -0
- data/lib/rom/command.rb +70 -41
- data/lib/rom/command_registry.rb +7 -18
- data/lib/rom/commands/class_interface.rb +7 -6
- data/lib/rom/commands/composite.rb +0 -1
- data/lib/rom/commands/graph.rb +7 -15
- data/lib/rom/commands/lazy/update.rb +1 -1
- data/lib/rom/configuration_dsl/command.rb +6 -8
- data/lib/rom/configuration_dsl/mapper.rb +2 -3
- data/lib/rom/configuration_dsl/mapper_dsl.rb +0 -1
- data/lib/rom/configuration_dsl/relation.rb +4 -4
- data/lib/rom/configuration_dsl.rb +0 -4
- data/lib/rom/constants.rb +1 -1
- data/lib/rom/container.rb +0 -2
- data/lib/rom/create_container.rb +0 -2
- data/lib/rom/data_proxy.rb +94 -0
- data/lib/rom/enumerable_dataset.rb +68 -0
- data/lib/rom/gateway.rb +23 -6
- data/lib/rom/global/plugin_dsl.rb +0 -2
- data/lib/rom/global.rb +0 -2
- data/lib/rom/initializer.rb +26 -0
- data/lib/rom/lint/gateway.rb +17 -0
- data/lib/rom/mapper_registry.rb +1 -1
- data/lib/rom/memory/commands.rb +0 -2
- data/lib/rom/memory/dataset.rb +1 -2
- data/lib/rom/memory/relation.rb +14 -1
- data/lib/rom/memory/schema.rb +13 -0
- data/lib/rom/plugin_registry.rb +1 -1
- data/lib/rom/plugins/configuration/configuration_dsl.rb +6 -2
- data/lib/rom/plugins/relation/key_inference.rb +4 -2
- data/lib/rom/plugins/relation/registry_reader.rb +5 -1
- data/lib/rom/registry.rb +50 -0
- data/lib/rom/relation/class_interface.rb +94 -26
- data/lib/rom/relation/curried.rb +15 -15
- data/lib/rom/relation/view_dsl.rb +31 -0
- data/lib/rom/relation.rb +49 -34
- data/lib/rom/schema/dsl.rb +7 -9
- data/lib/rom/schema/type.rb +115 -0
- data/lib/rom/schema.rb +218 -18
- data/lib/rom/setup/auto_registration.rb +20 -17
- data/lib/rom/setup/auto_registration_strategies/base.rb +8 -3
- data/lib/rom/setup/auto_registration_strategies/custom_namespace.rb +4 -3
- data/lib/rom/setup/auto_registration_strategies/no_namespace.rb +5 -4
- data/lib/rom/setup/auto_registration_strategies/with_namespace.rb +3 -3
- data/lib/rom/setup/finalize/finalize_commands.rb +1 -1
- data/lib/rom/setup/finalize/finalize_mappers.rb +1 -1
- data/lib/rom/setup/finalize/finalize_relations.rb +3 -1
- data/lib/rom/setup/finalize.rb +1 -1
- data/lib/rom/transaction.rb +24 -0
- data/lib/rom/types.rb +9 -1
- data/lib/rom/version.rb +1 -1
- data/lib/rom.rb +4 -8
- data/rom.gemspec +4 -3
- data/spec/integration/command_registry_spec.rb +1 -14
- data/spec/integration/commands/create_spec.rb +5 -25
- data/spec/integration/commands/delete_spec.rb +1 -1
- data/spec/integration/commands/error_handling_spec.rb +1 -1
- data/spec/integration/commands/graph_spec.rb +20 -14
- data/spec/integration/commands/update_spec.rb +4 -27
- data/spec/integration/commands_spec.rb +1 -1
- data/spec/integration/{repositories → gateways}/extending_relations_spec.rb +1 -1
- data/spec/integration/{repositories → gateways}/setting_logger_spec.rb +2 -2
- data/spec/integration/mappers/combine_spec.rb +1 -1
- data/spec/integration/mappers/deep_embedded_spec.rb +1 -1
- data/spec/integration/mappers/definition_dsl_spec.rb +1 -1
- data/spec/integration/mappers/embedded_spec.rb +1 -1
- data/spec/integration/mappers/exclude_spec.rb +1 -1
- data/spec/integration/mappers/fold_spec.rb +1 -1
- data/spec/integration/mappers/group_spec.rb +1 -1
- data/spec/integration/mappers/overwrite_attributes_value_spec.rb +1 -1
- data/spec/integration/mappers/prefix_separator_spec.rb +1 -1
- data/spec/integration/mappers/prefix_spec.rb +1 -1
- data/spec/integration/mappers/prefixing_attributes_spec.rb +1 -1
- data/spec/integration/mappers/registering_custom_mappers_spec.rb +1 -1
- data/spec/integration/mappers/renaming_attributes_spec.rb +1 -1
- data/spec/integration/mappers/reusing_mappers_spec.rb +1 -1
- data/spec/integration/mappers/step_spec.rb +1 -1
- data/spec/integration/mappers/symbolizing_attributes_spec.rb +1 -1
- data/spec/integration/mappers/unfold_spec.rb +1 -1
- data/spec/integration/mappers/ungroup_spec.rb +1 -1
- data/spec/integration/mappers/unwrap_spec.rb +2 -2
- data/spec/integration/mappers/wrap_spec.rb +1 -1
- data/spec/integration/memory/commands/create_spec.rb +1 -1
- data/spec/integration/memory/commands/delete_spec.rb +1 -1
- data/spec/integration/memory/commands/update_spec.rb +1 -1
- data/spec/integration/multi_env_spec.rb +1 -1
- data/spec/integration/multi_repo_spec.rb +1 -1
- data/spec/integration/relations/default_dataset_spec.rb +1 -1
- data/spec/integration/relations/reading_spec.rb +1 -1
- data/spec/integration/relations/registry_dsl_spec.rb +1 -1
- data/spec/integration/setup_spec.rb +10 -4
- data/spec/shared/command_graph.rb +8 -4
- data/spec/shared/enumerable_dataset.rb +1 -1
- data/spec/spec_helper.rb +7 -9
- data/spec/support/schema.rb +14 -0
- data/spec/unit/rom/array_dataset_spec.rb +59 -0
- data/spec/unit/rom/association_set_spec.rb +4 -0
- data/spec/unit/rom/auto_curry_spec.rb +63 -0
- data/spec/unit/rom/commands/graph_spec.rb +12 -11
- data/spec/unit/rom/commands/lazy_spec.rb +8 -5
- data/spec/unit/rom/commands/pre_and_post_processors_spec.rb +269 -0
- data/spec/unit/rom/commands/result_spec.rb +1 -1
- data/spec/unit/rom/commands_spec.rb +9 -3
- data/spec/unit/rom/configuration_spec.rb +1 -1
- data/spec/unit/rom/container_spec.rb +11 -5
- data/spec/unit/rom/create_container_spec.rb +1 -1
- data/spec/unit/rom/enumerable_dataset_spec.rb +15 -0
- data/spec/unit/rom/gateway_spec.rb +1 -1
- data/spec/unit/rom/mapper_registry_spec.rb +1 -1
- data/spec/unit/rom/memory/commands_spec.rb +1 -1
- data/spec/unit/rom/memory/dataset_spec.rb +1 -1
- data/spec/unit/rom/memory/{repository_spec.rb → gateway_spec.rb} +1 -1
- data/spec/unit/rom/memory/inheritance_spec.rb +32 -0
- data/spec/unit/rom/memory/relation_spec.rb +15 -3
- data/spec/unit/rom/memory/storage_spec.rb +1 -1
- data/spec/unit/rom/plugin_spec.rb +1 -1
- data/spec/unit/rom/plugins/relation/key_inference_spec.rb +1 -1
- data/spec/unit/rom/registry_spec.rb +86 -0
- data/spec/unit/rom/relation/attribute_reader_spec.rb +17 -0
- data/spec/unit/rom/relation/composite_spec.rb +1 -1
- data/spec/unit/rom/relation/graph_spec.rb +1 -1
- data/spec/unit/rom/relation/lazy/combine_spec.rb +1 -1
- data/spec/unit/rom/relation/lazy_spec.rb +1 -1
- data/spec/unit/rom/relation/loaded_spec.rb +1 -1
- data/spec/unit/rom/relation/schema_spec.rb +10 -6
- data/spec/unit/rom/relation/view_spec.rb +112 -0
- data/spec/unit/rom/relation_spec.rb +16 -2
- data/spec/unit/rom/schema/accessing_attributes_spec.rb +52 -0
- data/spec/unit/rom/schema/exclude_spec.rb +15 -0
- data/spec/unit/rom/schema/finalize_spec.rb +59 -0
- data/spec/unit/rom/schema/key_predicate_spec.rb +15 -0
- data/spec/unit/rom/schema/merge_spec.rb +17 -0
- data/spec/unit/rom/schema/prefix_spec.rb +16 -0
- data/spec/unit/rom/schema/project_spec.rb +15 -0
- data/spec/unit/rom/schema/rename_spec.rb +22 -0
- data/spec/unit/rom/schema/type_spec.rb +49 -0
- data/spec/unit/rom/schema/wrap_spec.rb +17 -0
- data/spec/unit/rom/schema_spec.rb +2 -2
- metadata +69 -17
- data/lib/rom/plugins/relation/view/dsl.rb +0 -32
- data/lib/rom/plugins/relation/view.rb +0 -95
- data/spec/unit/rom/plugins/relation/view_spec.rb +0 -51
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 58d0cbbb31e4ac734e6b569dcd7c0a1bd679bd89
|
4
|
+
data.tar.gz: d6f72e2b130a21ba81cc66400be6da7ea179aa6c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3ae3f83681a32b2f51629a49ab3ecde5c66d2ce2ce59e6dfdb36475343a73ff4515bda9e5aa5b7ab59fb7fd81777296ee7b98b221af621f1f37bd4ae42159442
|
7
|
+
data.tar.gz: b688b6b8430a4f9bbe4dd43dbe066813aa354adc5d0e519107be7c3c8e226abb8498c06c2bbbd4042d6498a2ea0c63e63a73396ad1fddf342740a1c438c14045
|
data/.travis.yml
CHANGED
@@ -5,11 +5,11 @@ cache: bundler
|
|
5
5
|
bundler_args: --without sql benchmarks console tools
|
6
6
|
script: "bundle exec rake ci"
|
7
7
|
after_success:
|
8
|
-
- '[
|
8
|
+
- '[ -d coverage ] && bundle exec codeclimate-test-reporter'
|
9
9
|
rvm:
|
10
|
-
- 2.
|
11
|
-
- 2.
|
12
|
-
- 2.
|
10
|
+
- 2.2.6
|
11
|
+
- 2.3.3
|
12
|
+
- 2.4.0
|
13
13
|
- rbx-3
|
14
14
|
- jruby-9.1.5.0
|
15
15
|
env:
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,36 @@
|
|
1
|
+
## v3.0.0 to-be-released
|
2
|
+
|
3
|
+
## Added
|
4
|
+
|
5
|
+
* Support for schemas in view definitions via `schema do ... end` block (evaluated in the context of the canonical schema) (solnic)
|
6
|
+
* Schemas have their own types with adapter-specific APIs (solnic)
|
7
|
+
* Schema attributes include meta properties `source` and `target` (for FKs) (solnic)
|
8
|
+
* Inferred schemas can have explicit attribute definitions for cases where inference didn't work (solnic)
|
9
|
+
* New schema APIs: `#project`, `#rename`, `#exclude`, `#prefix`, `#wrap` and `#merge` (solnic)
|
10
|
+
* New schema attribute APIs: `#name`, `#aliased`, `#aliased?`, `#prefixed`, `#prefixed?`, `#wrapped`, `#wrapped?`, `#source`, `#target`, `#primary_key?`, `#foreign_key?` (solnic)
|
11
|
+
* Schemas are coercible to arrays that include all attribute types (solnic)
|
12
|
+
* Automatic relation view projection via `Schema#call` (abstract method for adapters) (solnic)
|
13
|
+
* `Relation#new(dataset, new_opts)` interface (solnic)
|
14
|
+
* `Relation#[]` interface for convenient access to schema attributes (solnic)
|
15
|
+
* `Command` has now support for `before` and `after` hooks (solnic)
|
16
|
+
* New `Command#before` method for creating a command with before hook(s) at run-time (solnic)
|
17
|
+
* New `Command#after` method for creating a command with after hook(s) at run-time (solnic)
|
18
|
+
* New `Gateway#transaction` method runs code inside a transaction (flash-gordon)
|
19
|
+
|
20
|
+
## Changed
|
21
|
+
|
22
|
+
* [BREAKING] All relations have schemas now, empty by default (solnic)
|
23
|
+
* [BREAKING] `view` DSL is now part of the core relation API (solnic)
|
24
|
+
* [BREAKING] `view` DSL is based on schemas now, `header` was replaced with `schema` (solnic)
|
25
|
+
* [BREAKING] Deprecated `Command.validator` was removed (solnic)
|
26
|
+
* [internal] Renamed `relation` => `target` meta property in FK types (solnic)
|
27
|
+
* [internal] Use deprecations API from dry-core (flash-gordon)
|
28
|
+
* [internal] Use common constants from dry-core (EMPTY_HASH, EMPTY_ARRAY etc.) (flash-gordon)
|
29
|
+
* [internal] Internal ROM modules (array_dataset, enumerable_dataset, auto_curry, and data_proxy) were moved from rom-support to ROM itself (flash-gordon)
|
30
|
+
* [internal] rom-support dependency was removed (flash-gordon)
|
31
|
+
|
32
|
+
[Compare v2.0.2...v3.0.0](https://github.com/rom-rb/rom/compare/v2.0.2...v3.0.0)
|
33
|
+
|
1
34
|
## v2.0.2 2016-11-11
|
2
35
|
|
3
36
|
## Added
|
@@ -9,7 +42,7 @@
|
|
9
42
|
* Custom command input function is no longer overridden by schema hash (solnic)
|
10
43
|
* `Relation::Name#to_s` returns a string properly when there is no alias (solnic)
|
11
44
|
|
12
|
-
[Compare v2.0.1...v2.0.2](https://github.com/rom-rb/rom/compare/v2.0.
|
45
|
+
[Compare v2.0.1...v2.0.2](https://github.com/rom-rb/rom/compare/v2.0.1...v2.0.2)
|
13
46
|
|
14
47
|
## v2.0.1 2016-09-30
|
15
48
|
|
data/Gemfile
CHANGED
@@ -2,6 +2,8 @@ source 'https://rubygems.org'
|
|
2
2
|
|
3
3
|
gemspec
|
4
4
|
|
5
|
+
gem 'rom-mapper', git: 'https://github.com/rom-rb/rom-mapper.git', branch: 'master'
|
6
|
+
|
5
7
|
group :console do
|
6
8
|
gem 'pry'
|
7
9
|
gem 'pg', platforms: [:mri]
|
@@ -24,18 +26,30 @@ group :test do
|
|
24
26
|
end
|
25
27
|
|
26
28
|
group :sql do
|
27
|
-
gem 'rom-sql',
|
29
|
+
gem 'rom-sql', git: 'https://github.com/rom-rb/rom-sql.git', branch: 'master'
|
28
30
|
gem 'sequel'
|
29
31
|
gem 'jdbc-sqlite3', platforms: :jruby
|
32
|
+
gem 'jdbc-postgres', platforms: :jruby
|
30
33
|
gem 'sqlite3', platforms: [:mri, :rbx]
|
34
|
+
|
35
|
+
git_source(:github) { |repo_name| "https://github.com/#{repo_name}.git" }
|
36
|
+
|
37
|
+
platform :jruby do
|
38
|
+
github 'jruby/activerecord-jdbc-adapter', branch: 'rails-5' do
|
39
|
+
gem 'activerecord-jdbc-adapter'
|
40
|
+
gem 'activerecord-jdbcpostgresql-adapter'
|
41
|
+
end
|
42
|
+
end
|
31
43
|
end
|
32
44
|
|
33
45
|
group :benchmarks do
|
34
46
|
gem 'activerecord', '~> 5.0'
|
35
47
|
gem 'benchmark-ips', '~> 2.2.0'
|
36
|
-
gem 'rom-repository',
|
48
|
+
gem 'rom-repository', git: 'https://github.com/rom-rb/rom-repository.git', branch: 'master'
|
37
49
|
end
|
38
50
|
|
39
51
|
group :tools do
|
40
52
|
gem 'byebug', platform: :mri
|
53
|
+
gem 'mutant'
|
54
|
+
gem 'mutant-rspec'
|
41
55
|
end
|
data/Rakefile
CHANGED
@@ -11,8 +11,13 @@ task :"spec:isolation" do
|
|
11
11
|
end
|
12
12
|
end
|
13
13
|
|
14
|
-
|
15
|
-
|
14
|
+
if RUBY_ENGINE == 'jruby'
|
15
|
+
desc "Run CI tasks"
|
16
|
+
task ci: [:spec, :lint]
|
17
|
+
else
|
18
|
+
desc "Run CI tasks"
|
19
|
+
task ci: [:spec, :lint, :"spec:isolation"]
|
20
|
+
end
|
16
21
|
|
17
22
|
Rake::TestTask.new(:lint) do |test|
|
18
23
|
test.description = "Run adapter lint tests against memory adapter"
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require 'rom/initializer'
|
2
|
+
require 'rom/enumerable_dataset'
|
3
|
+
|
4
|
+
module ROM
|
5
|
+
# A helper module that adds data-proxy behavior to an array-like object
|
6
|
+
#
|
7
|
+
# @see EnumerableDataset
|
8
|
+
#
|
9
|
+
# @api public
|
10
|
+
module ArrayDataset
|
11
|
+
extend DataProxy::ClassMethods
|
12
|
+
include EnumerableDataset
|
13
|
+
|
14
|
+
# Extends the class with data-proxy behavior
|
15
|
+
#
|
16
|
+
# @api private
|
17
|
+
def self.included(klass)
|
18
|
+
klass.class_eval do
|
19
|
+
extend Initializer
|
20
|
+
include DataProxy
|
21
|
+
|
22
|
+
param :data
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
forward(
|
27
|
+
:*, :+, :-, :compact, :compact!, :flatten, :flatten!, :length, :pop,
|
28
|
+
:reverse, :reverse!, :sample, :size, :shift, :shuffle, :shuffle!,
|
29
|
+
:slice, :slice!, :sort!, :uniq, :uniq!, :unshift, :values_at
|
30
|
+
)
|
31
|
+
|
32
|
+
[
|
33
|
+
:map!, :combination, :cycle, :delete_if, :keep_if, :permutation, :reject!,
|
34
|
+
:select!, :sort_by!
|
35
|
+
].each do |method|
|
36
|
+
class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
37
|
+
def #{method}(*args, &block)
|
38
|
+
return to_enum unless block
|
39
|
+
self.class.new(data.send(:#{method}, *args, &block), options)
|
40
|
+
end
|
41
|
+
RUBY
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
data/lib/rom/association_set.rb
CHANGED
@@ -1,12 +1,14 @@
|
|
1
|
-
require '
|
2
|
-
require 'rom/
|
1
|
+
require 'dry/core/inflector'
|
2
|
+
require 'rom/registry'
|
3
3
|
|
4
4
|
module ROM
|
5
5
|
class AssociationSet < ROM::Registry
|
6
6
|
# @api private
|
7
7
|
def try(name, &block)
|
8
|
-
|
9
|
-
|
8
|
+
key = name.to_sym
|
9
|
+
|
10
|
+
if key?(key) || key?(singularize(key))
|
11
|
+
yield(self[key])
|
10
12
|
else
|
11
13
|
false
|
12
14
|
end
|
@@ -19,8 +21,12 @@ module ROM
|
|
19
21
|
if key?(key)
|
20
22
|
super
|
21
23
|
else
|
22
|
-
super(
|
24
|
+
super(singularize(key))
|
23
25
|
end
|
24
26
|
end
|
27
|
+
|
28
|
+
def singularize(key)
|
29
|
+
Dry::Core::Inflector.singularize(key).to_sym
|
30
|
+
end
|
25
31
|
end
|
26
32
|
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
module ROM
|
2
|
+
module AutoCurry
|
3
|
+
def self.extended(klass)
|
4
|
+
klass.define_singleton_method(:method_added) do |name|
|
5
|
+
return if auto_curry_busy?
|
6
|
+
auto_curry_guard { auto_curry(name) }
|
7
|
+
super(name)
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
def auto_curry_guard
|
12
|
+
@__auto_curry_busy__ = true
|
13
|
+
yield
|
14
|
+
ensure
|
15
|
+
@__auto_curry_busy__ = false
|
16
|
+
end
|
17
|
+
|
18
|
+
def auto_curry_busy?
|
19
|
+
@__auto_curry_busy__ ||= false
|
20
|
+
end
|
21
|
+
|
22
|
+
def auto_curried_methods
|
23
|
+
@__auto_curried_methods__ ||= []
|
24
|
+
end
|
25
|
+
|
26
|
+
def auto_curry(name, &block)
|
27
|
+
arity = instance_method(name).arity
|
28
|
+
|
29
|
+
return unless public_instance_methods.include?(name) && arity != 0
|
30
|
+
|
31
|
+
mod = Module.new
|
32
|
+
|
33
|
+
mod.module_eval do
|
34
|
+
define_method(name) do |*args|
|
35
|
+
response =
|
36
|
+
if arity < 0 || arity == args.size
|
37
|
+
super(*args)
|
38
|
+
else
|
39
|
+
self.class.curried.new(self, name: name, curry_args: args, arity: arity)
|
40
|
+
end
|
41
|
+
|
42
|
+
if block
|
43
|
+
response.instance_exec(&block)
|
44
|
+
else
|
45
|
+
response
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
auto_curried_methods << name
|
51
|
+
|
52
|
+
prepend(mod)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
data/lib/rom/command.rb
CHANGED
@@ -1,5 +1,8 @@
|
|
1
|
-
require '
|
2
|
-
require '
|
1
|
+
require 'dry/core/deprecations'
|
2
|
+
require 'dry/core/class_attributes'
|
3
|
+
|
4
|
+
require 'rom/types'
|
5
|
+
require 'rom/initializer'
|
3
6
|
require 'rom/pipeline'
|
4
7
|
|
5
8
|
require 'rom/commands/class_interface'
|
@@ -20,57 +23,33 @@ module ROM
|
|
20
23
|
#
|
21
24
|
# @private
|
22
25
|
class Command
|
23
|
-
|
24
|
-
|
26
|
+
extend Initializer
|
25
27
|
include Dry::Equalizer(:relation, :options)
|
26
28
|
include Commands
|
27
29
|
include Pipeline::Operator
|
28
30
|
|
29
|
-
extend
|
31
|
+
extend Dry::Core::ClassAttributes
|
30
32
|
extend ClassInterface
|
31
33
|
|
32
|
-
|
34
|
+
defines :adapter, :relation, :result, :input, :register_as, :restrictable, :before, :after
|
33
35
|
|
34
|
-
|
36
|
+
# @attr_reader [Relation] relation The command's relation
|
37
|
+
param :relation
|
35
38
|
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
option :
|
39
|
+
CommandType = Types::Strict::Symbol.enum(:create, :update, :delete)
|
40
|
+
Result = Types::Strict::Symbol.enum(:one, :many)
|
41
|
+
|
42
|
+
option :type, type: CommandType, optional: true
|
43
|
+
option :source, reader: true, optional: true, default: -> c { c.relation }
|
44
|
+
option :result, reader: true, type: Result
|
40
45
|
option :input, reader: true
|
41
|
-
option :curry_args,
|
46
|
+
option :curry_args, reader: true, default: -> _ { EMPTY_ARRAY }
|
47
|
+
option :before, Types::Coercible::Array, reader: true, as: :before_hooks, default: proc { EMPTY_ARRAY }
|
48
|
+
option :after, Types::Coercible::Array, reader: true, as: :after_hooks, default: proc { EMPTY_ARRAY }
|
42
49
|
|
43
50
|
input Hash
|
44
|
-
validator DEFAULT_VALIDATOR
|
45
51
|
result :many
|
46
52
|
|
47
|
-
# @deprecated
|
48
|
-
#
|
49
|
-
# @api public
|
50
|
-
def self.validator(vp = nil)
|
51
|
-
if defined?(@validator) && vp.nil?
|
52
|
-
@validator
|
53
|
-
else
|
54
|
-
unless vp.equal?(DEFAULT_VALIDATOR)
|
55
|
-
Deprecations.announce(
|
56
|
-
"#{name}.validator",
|
57
|
-
'Please handle validation before calling commands'
|
58
|
-
)
|
59
|
-
end
|
60
|
-
super
|
61
|
-
end
|
62
|
-
end
|
63
|
-
|
64
|
-
# @attr_reader [Relation] relation The command's relation
|
65
|
-
attr_reader :relation
|
66
|
-
|
67
|
-
# @api private
|
68
|
-
def initialize(relation, options = EMPTY_HASH)
|
69
|
-
super
|
70
|
-
@relation = relation
|
71
|
-
@source = options[:source] || relation
|
72
|
-
end
|
73
|
-
|
74
53
|
# Return name of this command's relation
|
75
54
|
#
|
76
55
|
# @return [ROM::Relation::Name]
|
@@ -107,7 +86,25 @@ module ROM
|
|
107
86
|
#
|
108
87
|
# @api public
|
109
88
|
def call(*args, &block)
|
110
|
-
tuples =
|
89
|
+
tuples =
|
90
|
+
if hooks?
|
91
|
+
prepared =
|
92
|
+
if curried?
|
93
|
+
apply_hooks(before_hooks, *(curry_args + args))
|
94
|
+
else
|
95
|
+
apply_hooks(before_hooks, *args)
|
96
|
+
end
|
97
|
+
|
98
|
+
result = prepared ? execute(prepared, &block) : execute(&block)
|
99
|
+
|
100
|
+
if curried?
|
101
|
+
apply_hooks(after_hooks, result, *args)
|
102
|
+
else
|
103
|
+
apply_hooks(after_hooks, result, *args[1..args.size-1])
|
104
|
+
end
|
105
|
+
else
|
106
|
+
execute(*(curry_args + args), &block)
|
107
|
+
end
|
111
108
|
|
112
109
|
if one?
|
113
110
|
tuples.first
|
@@ -133,6 +130,16 @@ module ROM
|
|
133
130
|
end
|
134
131
|
alias_method :with, :curry
|
135
132
|
|
133
|
+
# @api public
|
134
|
+
def curried?
|
135
|
+
curry_args.size > 0
|
136
|
+
end
|
137
|
+
|
138
|
+
# @api private
|
139
|
+
def hooks?
|
140
|
+
before_hooks.size > 0 || after_hooks.size > 0
|
141
|
+
end
|
142
|
+
|
136
143
|
# @api public
|
137
144
|
def combine(*others)
|
138
145
|
Graph.new(self, others)
|
@@ -163,11 +170,33 @@ module ROM
|
|
163
170
|
self.class.build(new_relation, options.merge(source: relation))
|
164
171
|
end
|
165
172
|
|
173
|
+
# @api public
|
174
|
+
def before(*hooks)
|
175
|
+
self.class.new(relation, options.merge(before: hooks))
|
176
|
+
end
|
177
|
+
|
178
|
+
# @api public
|
179
|
+
def after(*hooks)
|
180
|
+
self.class.new(relation, options.merge(after: hooks))
|
181
|
+
end
|
182
|
+
|
166
183
|
private
|
167
184
|
|
168
185
|
# @api private
|
169
186
|
def composite_class
|
170
187
|
Command::Composite
|
171
188
|
end
|
189
|
+
|
190
|
+
# @api private
|
191
|
+
def apply_hooks(hooks, tuples, *args)
|
192
|
+
hooks.reduce(tuples) do |a, e|
|
193
|
+
if e.is_a?(Hash)
|
194
|
+
hook_meth, hook_args = e.to_a.flatten(1)
|
195
|
+
__send__(hook_meth, a, *args, **hook_args)
|
196
|
+
else
|
197
|
+
__send__(e, a, *args)
|
198
|
+
end
|
199
|
+
end
|
200
|
+
end
|
172
201
|
end
|
173
202
|
end
|
data/lib/rom/command_registry.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
require 'rom/types'
|
1
2
|
require 'rom/commands/result'
|
2
3
|
|
3
4
|
module ROM
|
@@ -5,40 +6,28 @@ module ROM
|
|
5
6
|
#
|
6
7
|
# @api public
|
7
8
|
class CommandRegistry
|
9
|
+
extend Initializer
|
8
10
|
include Commands
|
9
|
-
include Options
|
10
11
|
|
11
12
|
CommandNotFoundError = Class.new(KeyError)
|
13
|
+
RegistryType = Types.Definition(Registry) | Types.Constructor(Registry) { |r| Registry.new(r, self.class.name) }
|
12
14
|
|
13
15
|
# Name of the relation from which commands are under
|
14
16
|
#
|
15
17
|
# @return [String]
|
16
18
|
#
|
17
19
|
# @api private
|
18
|
-
|
20
|
+
param :relation_name
|
19
21
|
|
20
22
|
# Internal command registry
|
21
23
|
#
|
22
24
|
# @return [Registry]
|
23
25
|
#
|
24
26
|
# @api private
|
25
|
-
|
27
|
+
param :registry, type: RegistryType
|
26
28
|
|
27
|
-
option :mappers, reader: true
|
28
|
-
option :mapper, reader: true
|
29
|
-
|
30
|
-
# @api private
|
31
|
-
def initialize(relation_name, elements, options = EMPTY_HASH)
|
32
|
-
super
|
33
|
-
|
34
|
-
@relation_name = relation_name
|
35
|
-
@registry =
|
36
|
-
if elements.is_a?(Registry)
|
37
|
-
elements
|
38
|
-
else
|
39
|
-
Registry.new(elements, self.class.name)
|
40
|
-
end
|
41
|
-
end
|
29
|
+
option :mappers, reader: true, optional: true
|
30
|
+
option :mapper, reader: true, optional: true
|
42
31
|
|
43
32
|
# Try to execute a command in a block
|
44
33
|
#
|
@@ -1,4 +1,5 @@
|
|
1
|
-
require '
|
1
|
+
require 'dry/core/class_builder'
|
2
|
+
require 'dry/core/inflector'
|
2
3
|
|
3
4
|
module ROM
|
4
5
|
# Base command class with factory class-level interface and setup-related logic
|
@@ -20,7 +21,7 @@ module ROM
|
|
20
21
|
#
|
21
22
|
# @api public
|
22
23
|
def [](adapter)
|
23
|
-
adapter_namespace(adapter).const_get(Inflector.demodulize(name))
|
24
|
+
adapter_namespace(adapter).const_get(Dry::Core::Inflector.demodulize(name))
|
24
25
|
end
|
25
26
|
|
26
27
|
# Return namespaces that contains command subclasses of a specific adapter
|
@@ -65,8 +66,8 @@ module ROM
|
|
65
66
|
#
|
66
67
|
# @api public
|
67
68
|
def create_class(name, type, &block)
|
68
|
-
klass = ClassBuilder
|
69
|
-
.new(name: "#{Inflector.classify(type)}[:#{name}]", parent: type)
|
69
|
+
klass = Dry::Core::ClassBuilder
|
70
|
+
.new(name: "#{Dry::Core::Inflector.classify(type)}[:#{name}]", parent: type)
|
70
71
|
.call
|
71
72
|
|
72
73
|
if block
|
@@ -113,7 +114,7 @@ module ROM
|
|
113
114
|
#
|
114
115
|
# @api private
|
115
116
|
def default_name
|
116
|
-
Inflector.underscore(Inflector.demodulize(name)).to_sym
|
117
|
+
Dry::Core::Inflector.underscore(Dry::Core::Inflector.demodulize(name)).to_sym
|
117
118
|
end
|
118
119
|
|
119
120
|
# Return default options based on class macros
|
@@ -122,7 +123,7 @@ module ROM
|
|
122
123
|
#
|
123
124
|
# @api private
|
124
125
|
def options
|
125
|
-
{ input: input,
|
126
|
+
{ input: input, result: result, before: before, after: after }
|
126
127
|
end
|
127
128
|
|
128
129
|
# @api private
|
data/lib/rom/commands/graph.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
|
+
require 'rom/initializer'
|
1
2
|
require 'rom/pipeline'
|
2
|
-
require 'rom/support/options'
|
3
3
|
require 'rom/commands/graph/class_interface'
|
4
4
|
|
5
5
|
module ROM
|
@@ -8,35 +8,27 @@ module ROM
|
|
8
8
|
#
|
9
9
|
# @api private
|
10
10
|
class Graph
|
11
|
+
extend Initializer
|
11
12
|
include Dry::Equalizer(:root, :nodes)
|
12
13
|
|
13
14
|
extend ClassInterface
|
14
15
|
|
15
|
-
include Options
|
16
16
|
include Pipeline
|
17
17
|
include Pipeline::Proxy
|
18
18
|
|
19
19
|
# @attr_reader [Command] root The root command
|
20
|
-
|
20
|
+
param :root
|
21
21
|
|
22
22
|
# @attr_reader [Array<Command>] nodes The child commands
|
23
|
-
|
24
|
-
|
25
|
-
# @attr_reader [Symbol] root's relation name
|
26
|
-
attr_reader :name
|
23
|
+
param :nodes
|
27
24
|
|
28
25
|
alias_method :left, :root
|
29
26
|
alias_method :right, :nodes
|
30
27
|
|
31
|
-
|
28
|
+
# @attr_reader [Symbol] root's relation name
|
29
|
+
option :name, reader: true, default: -> g { g.root.name }
|
32
30
|
|
33
|
-
|
34
|
-
def initialize(root, nodes, options = EMPTY_HASH)
|
35
|
-
super
|
36
|
-
@root = root
|
37
|
-
@nodes = nodes
|
38
|
-
@name = root.name
|
39
|
-
end
|
31
|
+
option :mappers, reader: true, default: proc { MapperRegistry.new }
|
40
32
|
|
41
33
|
# Calls root and all nodes with the result from root
|
42
34
|
#
|
@@ -20,7 +20,7 @@ module ROM
|
|
20
20
|
|
21
21
|
if input.is_a?(Array)
|
22
22
|
input.map.with_index do |item, index|
|
23
|
-
command_proc[command, last, item].call(item,
|
23
|
+
command_proc[command, last, item].call(item, *args[1..size-1])
|
24
24
|
end
|
25
25
|
else
|
26
26
|
command_proc[command, *(size > 1 ? [last, input] : [input])]
|
@@ -1,7 +1,5 @@
|
|
1
|
-
require '
|
2
|
-
|
3
|
-
require 'rom/support/inflector'
|
4
|
-
require 'rom/support/class_builder'
|
1
|
+
require 'dry/core/inflector'
|
2
|
+
require 'dry/core/class_builder'
|
5
3
|
|
6
4
|
module ROM
|
7
5
|
module ConfigurationDSL
|
@@ -16,12 +14,12 @@ module ROM
|
|
16
14
|
# @api private
|
17
15
|
def self.build_class(name, relation, options = EMPTY_HASH, &block)
|
18
16
|
type = options.fetch(:type) { name }
|
19
|
-
command_type = Inflector.classify(type)
|
17
|
+
command_type = Dry::Core::Inflector.classify(type)
|
20
18
|
adapter = options.fetch(:adapter)
|
21
19
|
parent = ROM::Command.adapter_namespace(adapter).const_get(command_type)
|
22
20
|
class_name = generate_class_name(adapter, command_type, relation)
|
23
21
|
|
24
|
-
ClassBuilder.new(name: class_name, parent: parent).call do |klass|
|
22
|
+
Dry::Core::ClassBuilder.new(name: class_name, parent: parent).call do |klass|
|
25
23
|
klass.register_as(name)
|
26
24
|
klass.relation(relation)
|
27
25
|
klass.class_eval(&block) if block
|
@@ -33,9 +31,9 @@ module ROM
|
|
33
31
|
# @api private
|
34
32
|
def self.generate_class_name(adapter, command_type, relation)
|
35
33
|
pieces = ['ROM']
|
36
|
-
pieces << Inflector.classify(adapter)
|
34
|
+
pieces << Dry::Core::Inflector.classify(adapter)
|
37
35
|
pieces << 'Commands'
|
38
|
-
pieces << "#{command_type}[#{Inflector.classify(relation)}s]"
|
36
|
+
pieces << "#{command_type}[#{Dry::Core::Inflector.classify(relation)}s]"
|
39
37
|
pieces.join('::')
|
40
38
|
end
|
41
39
|
end
|
@@ -1,5 +1,4 @@
|
|
1
|
-
require '
|
2
|
-
require 'rom/support/class_builder'
|
1
|
+
require 'dry/core/class_builder'
|
3
2
|
|
4
3
|
module ROM
|
5
4
|
module ConfigurationDSL
|
@@ -25,7 +24,7 @@ module ROM
|
|
25
24
|
ROM::Mapper
|
26
25
|
end
|
27
26
|
|
28
|
-
ClassBuilder.new(name: class_name, parent: parent_class).call do |klass|
|
27
|
+
Dry::Core::ClassBuilder.new(name: class_name, parent: parent_class).call do |klass|
|
29
28
|
klass.relation(name)
|
30
29
|
klass.inherit_header(inherit_header)
|
31
30
|
|
@@ -1,5 +1,5 @@
|
|
1
|
-
require '
|
2
|
-
require '
|
1
|
+
require 'dry/core/class_builder'
|
2
|
+
require 'dry/core/inflector'
|
3
3
|
|
4
4
|
module ROM
|
5
5
|
module ConfigurationDSL
|
@@ -13,10 +13,10 @@ module ROM
|
|
13
13
|
#
|
14
14
|
# @api private
|
15
15
|
def self.build_class(name, options = EMPTY_HASH)
|
16
|
-
class_name = "ROM::Relation[#{Inflector.camelize(name)}]"
|
16
|
+
class_name = "ROM::Relation[#{Dry::Core::Inflector.camelize(name)}]"
|
17
17
|
adapter = options.fetch(:adapter)
|
18
18
|
|
19
|
-
ClassBuilder.new(name: class_name, parent: ROM::Relation[adapter]).call do |klass|
|
19
|
+
Dry::Core::ClassBuilder.new(name: class_name, parent: ROM::Relation[adapter]).call do |klass|
|
20
20
|
klass.gateway(options.fetch(:gateway, :default))
|
21
21
|
klass.dataset(name)
|
22
22
|
end
|