rom 2.0.2 → 3.0.0.beta1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (149) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +4 -4
  3. data/CHANGELOG.md +34 -1
  4. data/Gemfile +16 -2
  5. data/Rakefile +7 -2
  6. data/lib/rom/array_dataset.rb +44 -0
  7. data/lib/rom/association_set.rb +11 -5
  8. data/lib/rom/auto_curry.rb +55 -0
  9. data/lib/rom/command.rb +70 -41
  10. data/lib/rom/command_registry.rb +7 -18
  11. data/lib/rom/commands/class_interface.rb +7 -6
  12. data/lib/rom/commands/composite.rb +0 -1
  13. data/lib/rom/commands/graph.rb +7 -15
  14. data/lib/rom/commands/lazy/update.rb +1 -1
  15. data/lib/rom/configuration_dsl/command.rb +6 -8
  16. data/lib/rom/configuration_dsl/mapper.rb +2 -3
  17. data/lib/rom/configuration_dsl/mapper_dsl.rb +0 -1
  18. data/lib/rom/configuration_dsl/relation.rb +4 -4
  19. data/lib/rom/configuration_dsl.rb +0 -4
  20. data/lib/rom/constants.rb +1 -1
  21. data/lib/rom/container.rb +0 -2
  22. data/lib/rom/create_container.rb +0 -2
  23. data/lib/rom/data_proxy.rb +94 -0
  24. data/lib/rom/enumerable_dataset.rb +68 -0
  25. data/lib/rom/gateway.rb +23 -6
  26. data/lib/rom/global/plugin_dsl.rb +0 -2
  27. data/lib/rom/global.rb +0 -2
  28. data/lib/rom/initializer.rb +26 -0
  29. data/lib/rom/lint/gateway.rb +17 -0
  30. data/lib/rom/mapper_registry.rb +1 -1
  31. data/lib/rom/memory/commands.rb +0 -2
  32. data/lib/rom/memory/dataset.rb +1 -2
  33. data/lib/rom/memory/relation.rb +14 -1
  34. data/lib/rom/memory/schema.rb +13 -0
  35. data/lib/rom/plugin_registry.rb +1 -1
  36. data/lib/rom/plugins/configuration/configuration_dsl.rb +6 -2
  37. data/lib/rom/plugins/relation/key_inference.rb +4 -2
  38. data/lib/rom/plugins/relation/registry_reader.rb +5 -1
  39. data/lib/rom/registry.rb +50 -0
  40. data/lib/rom/relation/class_interface.rb +94 -26
  41. data/lib/rom/relation/curried.rb +15 -15
  42. data/lib/rom/relation/view_dsl.rb +31 -0
  43. data/lib/rom/relation.rb +49 -34
  44. data/lib/rom/schema/dsl.rb +7 -9
  45. data/lib/rom/schema/type.rb +115 -0
  46. data/lib/rom/schema.rb +218 -18
  47. data/lib/rom/setup/auto_registration.rb +20 -17
  48. data/lib/rom/setup/auto_registration_strategies/base.rb +8 -3
  49. data/lib/rom/setup/auto_registration_strategies/custom_namespace.rb +4 -3
  50. data/lib/rom/setup/auto_registration_strategies/no_namespace.rb +5 -4
  51. data/lib/rom/setup/auto_registration_strategies/with_namespace.rb +3 -3
  52. data/lib/rom/setup/finalize/finalize_commands.rb +1 -1
  53. data/lib/rom/setup/finalize/finalize_mappers.rb +1 -1
  54. data/lib/rom/setup/finalize/finalize_relations.rb +3 -1
  55. data/lib/rom/setup/finalize.rb +1 -1
  56. data/lib/rom/transaction.rb +24 -0
  57. data/lib/rom/types.rb +9 -1
  58. data/lib/rom/version.rb +1 -1
  59. data/lib/rom.rb +4 -8
  60. data/rom.gemspec +4 -3
  61. data/spec/integration/command_registry_spec.rb +1 -14
  62. data/spec/integration/commands/create_spec.rb +5 -25
  63. data/spec/integration/commands/delete_spec.rb +1 -1
  64. data/spec/integration/commands/error_handling_spec.rb +1 -1
  65. data/spec/integration/commands/graph_spec.rb +20 -14
  66. data/spec/integration/commands/update_spec.rb +4 -27
  67. data/spec/integration/commands_spec.rb +1 -1
  68. data/spec/integration/{repositories → gateways}/extending_relations_spec.rb +1 -1
  69. data/spec/integration/{repositories → gateways}/setting_logger_spec.rb +2 -2
  70. data/spec/integration/mappers/combine_spec.rb +1 -1
  71. data/spec/integration/mappers/deep_embedded_spec.rb +1 -1
  72. data/spec/integration/mappers/definition_dsl_spec.rb +1 -1
  73. data/spec/integration/mappers/embedded_spec.rb +1 -1
  74. data/spec/integration/mappers/exclude_spec.rb +1 -1
  75. data/spec/integration/mappers/fold_spec.rb +1 -1
  76. data/spec/integration/mappers/group_spec.rb +1 -1
  77. data/spec/integration/mappers/overwrite_attributes_value_spec.rb +1 -1
  78. data/spec/integration/mappers/prefix_separator_spec.rb +1 -1
  79. data/spec/integration/mappers/prefix_spec.rb +1 -1
  80. data/spec/integration/mappers/prefixing_attributes_spec.rb +1 -1
  81. data/spec/integration/mappers/registering_custom_mappers_spec.rb +1 -1
  82. data/spec/integration/mappers/renaming_attributes_spec.rb +1 -1
  83. data/spec/integration/mappers/reusing_mappers_spec.rb +1 -1
  84. data/spec/integration/mappers/step_spec.rb +1 -1
  85. data/spec/integration/mappers/symbolizing_attributes_spec.rb +1 -1
  86. data/spec/integration/mappers/unfold_spec.rb +1 -1
  87. data/spec/integration/mappers/ungroup_spec.rb +1 -1
  88. data/spec/integration/mappers/unwrap_spec.rb +2 -2
  89. data/spec/integration/mappers/wrap_spec.rb +1 -1
  90. data/spec/integration/memory/commands/create_spec.rb +1 -1
  91. data/spec/integration/memory/commands/delete_spec.rb +1 -1
  92. data/spec/integration/memory/commands/update_spec.rb +1 -1
  93. data/spec/integration/multi_env_spec.rb +1 -1
  94. data/spec/integration/multi_repo_spec.rb +1 -1
  95. data/spec/integration/relations/default_dataset_spec.rb +1 -1
  96. data/spec/integration/relations/reading_spec.rb +1 -1
  97. data/spec/integration/relations/registry_dsl_spec.rb +1 -1
  98. data/spec/integration/setup_spec.rb +10 -4
  99. data/spec/shared/command_graph.rb +8 -4
  100. data/spec/shared/enumerable_dataset.rb +1 -1
  101. data/spec/spec_helper.rb +7 -9
  102. data/spec/support/schema.rb +14 -0
  103. data/spec/unit/rom/array_dataset_spec.rb +59 -0
  104. data/spec/unit/rom/association_set_spec.rb +4 -0
  105. data/spec/unit/rom/auto_curry_spec.rb +63 -0
  106. data/spec/unit/rom/commands/graph_spec.rb +12 -11
  107. data/spec/unit/rom/commands/lazy_spec.rb +8 -5
  108. data/spec/unit/rom/commands/pre_and_post_processors_spec.rb +269 -0
  109. data/spec/unit/rom/commands/result_spec.rb +1 -1
  110. data/spec/unit/rom/commands_spec.rb +9 -3
  111. data/spec/unit/rom/configuration_spec.rb +1 -1
  112. data/spec/unit/rom/container_spec.rb +11 -5
  113. data/spec/unit/rom/create_container_spec.rb +1 -1
  114. data/spec/unit/rom/enumerable_dataset_spec.rb +15 -0
  115. data/spec/unit/rom/gateway_spec.rb +1 -1
  116. data/spec/unit/rom/mapper_registry_spec.rb +1 -1
  117. data/spec/unit/rom/memory/commands_spec.rb +1 -1
  118. data/spec/unit/rom/memory/dataset_spec.rb +1 -1
  119. data/spec/unit/rom/memory/{repository_spec.rb → gateway_spec.rb} +1 -1
  120. data/spec/unit/rom/memory/inheritance_spec.rb +32 -0
  121. data/spec/unit/rom/memory/relation_spec.rb +15 -3
  122. data/spec/unit/rom/memory/storage_spec.rb +1 -1
  123. data/spec/unit/rom/plugin_spec.rb +1 -1
  124. data/spec/unit/rom/plugins/relation/key_inference_spec.rb +1 -1
  125. data/spec/unit/rom/registry_spec.rb +86 -0
  126. data/spec/unit/rom/relation/attribute_reader_spec.rb +17 -0
  127. data/spec/unit/rom/relation/composite_spec.rb +1 -1
  128. data/spec/unit/rom/relation/graph_spec.rb +1 -1
  129. data/spec/unit/rom/relation/lazy/combine_spec.rb +1 -1
  130. data/spec/unit/rom/relation/lazy_spec.rb +1 -1
  131. data/spec/unit/rom/relation/loaded_spec.rb +1 -1
  132. data/spec/unit/rom/relation/schema_spec.rb +10 -6
  133. data/spec/unit/rom/relation/view_spec.rb +112 -0
  134. data/spec/unit/rom/relation_spec.rb +16 -2
  135. data/spec/unit/rom/schema/accessing_attributes_spec.rb +52 -0
  136. data/spec/unit/rom/schema/exclude_spec.rb +15 -0
  137. data/spec/unit/rom/schema/finalize_spec.rb +59 -0
  138. data/spec/unit/rom/schema/key_predicate_spec.rb +15 -0
  139. data/spec/unit/rom/schema/merge_spec.rb +17 -0
  140. data/spec/unit/rom/schema/prefix_spec.rb +16 -0
  141. data/spec/unit/rom/schema/project_spec.rb +15 -0
  142. data/spec/unit/rom/schema/rename_spec.rb +22 -0
  143. data/spec/unit/rom/schema/type_spec.rb +49 -0
  144. data/spec/unit/rom/schema/wrap_spec.rb +17 -0
  145. data/spec/unit/rom/schema_spec.rb +2 -2
  146. metadata +69 -17
  147. data/lib/rom/plugins/relation/view/dsl.rb +0 -32
  148. data/lib/rom/plugins/relation/view.rb +0 -95
  149. 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: e6dd420bd1787efc67261de110b316f6b5c92ae8
4
- data.tar.gz: e9f8fb3dbc40528ac46f6427d7b7238c162980bd
3
+ metadata.gz: 58d0cbbb31e4ac734e6b569dcd7c0a1bd679bd89
4
+ data.tar.gz: d6f72e2b130a21ba81cc66400be6da7ea179aa6c
5
5
  SHA512:
6
- metadata.gz: 6a48171fa2e771fec4e68e14b99e4f78cfd31f6d5162ff5f14546f41d6970b44c8522304cfa9546cff203967696853002e3524f714023d7ac0fd5ea086d7ea9f
7
- data.tar.gz: 34e9a0f63fabaf30897d767db9b8d26e1ac92cd0661cff7bdb5b1f27979fe56feb9f6b0c12ae7305f514c623322e270009ecd3ce35e51867bfdac5a199393408
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
- - '[ "$TRAVIS_RUBY_VERSION" = "2.3.1" ] && [ "$TRAVIS_BRANCH" = "master" ] && bundle exec codeclimate-test-reporter'
8
+ - '[ -d coverage ] && bundle exec codeclimate-test-reporter'
9
9
  rvm:
10
- - 2.1
11
- - 2.2
12
- - 2.3.1
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.0...v2.0.2)
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', github: 'rom-rb/rom-sql', branch: 'master'
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', github: 'rom-rb/rom-repository', branch: 'master'
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
- desc "Run CI tasks"
15
- task ci: [:spec, :lint, :"spec:isolation"]
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
@@ -1,12 +1,14 @@
1
- require 'rom/support/registry'
2
- require 'rom/support/inflector'
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
- if key?(name)
9
- yield(self[name])
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(Inflector.singularize(key))
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 'rom/support/deprecations'
2
- require 'rom/support/options'
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
- DEFAULT_VALIDATOR = proc {}
24
-
26
+ extend Initializer
25
27
  include Dry::Equalizer(:relation, :options)
26
28
  include Commands
27
29
  include Pipeline::Operator
28
30
 
29
- extend ClassMacros
31
+ extend Dry::Core::ClassAttributes
30
32
  extend ClassInterface
31
33
 
32
- include Options
34
+ defines :adapter, :relation, :result, :input, :register_as, :restrictable, :before, :after
33
35
 
34
- defines :adapter, :relation, :result, :input, :validator, :register_as, :restrictable
36
+ # @attr_reader [Relation] relation The command's relation
37
+ param :relation
35
38
 
36
- option :type, allow: [:create, :update, :delete]
37
- option :source, reader: true
38
- option :result, reader: true, allow: [:one, :many]
39
- option :validator, reader: true
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, type: Array, reader: true, default: EMPTY_ARRAY
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 = execute(*(curry_args + args), &block)
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
@@ -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
- attr_reader :relation_name
20
+ param :relation_name
19
21
 
20
22
  # Internal command registry
21
23
  #
22
24
  # @return [Registry]
23
25
  #
24
26
  # @api private
25
- attr_reader :registry
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 'rom/support/class_builder'
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, validator: validator, result: result }
126
+ { input: input, result: result, before: before, after: after }
126
127
  end
127
128
 
128
129
  # @api private
@@ -1,5 +1,4 @@
1
1
  require 'rom/pipeline'
2
- require 'rom/support/constants'
3
2
 
4
3
  module ROM
5
4
  module Commands
@@ -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
- attr_reader :root
20
+ param :root
21
21
 
22
22
  # @attr_reader [Array<Command>] nodes The child commands
23
- attr_reader :nodes
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
- option :mappers, reader: true, default: proc { MapperRegistry.new }
28
+ # @attr_reader [Symbol] root's relation name
29
+ option :name, reader: true, default: -> g { g.root.name }
32
30
 
33
- # @api private
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, *args[1..size-1])
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 'rom/support/constants'
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 'rom/support/constants'
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,4 +1,3 @@
1
- require 'rom/support/constants'
2
1
  require 'rom/configuration_dsl/mapper'
3
2
 
4
3
  module ROM
@@ -1,5 +1,5 @@
1
- require 'rom/support/constants'
2
- require 'rom/support/class_builder'
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