aggregate_root 0.39.0 → 0.40.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 07b31561cc74b2f7be4a3a714f2af9e9f1b82a6567707249da9d16f8271f7f2f
4
- data.tar.gz: 612fdb3ec19422a7885ed38c64f70f241fa67b34270be0ab708ef3186581d24d
3
+ metadata.gz: 6af35e06f7f261f5275b2e0f74b4abba41d7437a94d9527d66e7add0bf6d3788
4
+ data.tar.gz: fe132199dc2121bdb0bf5aa2591714aab84553a90a270307f79890b0276fca6a
5
5
  SHA512:
6
- metadata.gz: d55999302930c6c01dd9275f0d0bd092a33c078d09c61d69703fa91f18715b5330e50c3e3d752bfece462aecaf1f0200b58fea52bf891035666c9e6a2430cc43
7
- data.tar.gz: 3601973a69042ad88e2aa0f24091cc2aad120b4c5d265b98587a72def5b8f4cb456f161c19dcd34cb1bfbd4e625e623fd0ce64fbb74997b3cad60b7ac543b4bc
6
+ metadata.gz: 7157ba51608adc985fe90e595c7413b20ff15445d7c0830f05199c130f9449a4ac3f566b616beade6c19c4511168b078603f37e1dd79a4818f89c426c7b2f4fe
7
+ data.tar.gz: 50fe99d76b6073c9068a0cb93dd6775839cda59aed9a4f761adaa097b11316e9e3c19dffd94102b6fdc75cf769f055977b1a5ee67752e18bdc577bb78de3b960
data/Gemfile CHANGED
@@ -4,4 +4,7 @@ gemspec
4
4
 
5
5
  eval_gemfile File.expand_path('../support/bundler/Gemfile.shared', __dir__)
6
6
 
7
- gem 'ruby_event_store', path: '../ruby_event_store'
7
+ gem 'ruby_event_store', path: '../ruby_event_store'
8
+ gem 'protobuf_nested_struct'
9
+ gem 'google-protobuf', '~> 3.7.0'
10
+ gem 'activesupport', '~> 5.0'
@@ -25,5 +25,5 @@ Gem::Specification.new do |spec|
25
25
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
26
26
  spec.require_paths = ['lib']
27
27
 
28
- spec.add_dependency 'ruby_event_store', '= 0.39.0'
28
+ spec.add_dependency 'ruby_event_store', '= 0.40.0'
29
29
  end
@@ -3,92 +3,83 @@ require 'aggregate_root/configuration'
3
3
  require 'aggregate_root/transform'
4
4
  require 'aggregate_root/default_apply_strategy'
5
5
  require 'aggregate_root/repository'
6
+ require 'aggregate_root/instrumented_repository'
7
+
6
8
 
7
9
  module AggregateRoot
8
- module ClassMethods
10
+ module OnDSL
9
11
  def on(*event_klasses, &block)
10
12
  event_klasses.each do |event_klass|
11
- name = event_klass.name || raise(ArgumentError, "Anonymous class is missing name")
13
+ name = event_klass.to_s
14
+ raise(ArgumentError, "Anonymous class is missing name") if name.start_with? "#<Class:"
12
15
  handler_name = "on_#{name}"
13
16
  define_method(handler_name, &block)
14
17
  @on_methods ||= {}
15
- @on_methods[event_klass]=handler_name
18
+ @on_methods[name] = handler_name
16
19
  private(handler_name)
17
20
  end
18
21
  end
19
22
 
20
23
  def on_methods
21
- ancestors.
22
- select{|k| k.instance_variables.include?(:@on_methods)}.
23
- map{|k| k.instance_variable_get(:@on_methods) }.
24
- inject({}, &:merge)
24
+ @on_methods ||= {}
25
+ (superclass.respond_to?(:on_methods) ? superclass.on_methods : {}).merge(@on_methods)
25
26
  end
26
27
  end
27
28
 
28
- def self.included(host_class)
29
- host_class.extend(ClassMethods)
30
- end
31
-
32
- def apply(*events)
33
- events.each do |event|
34
- apply_strategy.(self, event)
35
- unpublished << event
29
+ module Constructor
30
+ def new
31
+ super().tap do |instance|
32
+ instance.instance_variable_set(:@version, -1)
33
+ instance.instance_variable_set(:@unpublished_events, [])
34
+ end
36
35
  end
37
36
  end
38
37
 
39
- def version
40
- @version ||= -1
41
- end
38
+ module AggregateMethods
39
+ def apply(*events)
40
+ events.each do |event|
41
+ apply_strategy.(self, event)
42
+ @unpublished_events << event
43
+ end
44
+ end
42
45
 
43
- def version=(value)
44
- @unpublished_events = nil
45
- @version = value
46
- end
46
+ def version
47
+ @version
48
+ end
47
49
 
48
- def unpublished_events
49
- unpublished.each
50
- end
50
+ def version=(value)
51
+ @unpublished_events = []
52
+ @version = value
53
+ end
51
54
 
52
- def load(stream_name, event_store: default_event_store)
53
- warn <<~EOW
54
- Method `load` on aggregate is deprecated. Use AggregateRoot::Repository instead.
55
- Instead of: `order = Order.new.load("OrderStreamHere")`
56
- you need to have code:
57
- ```
58
- repository = AggregateRoot::Repository.new
59
- order = repository.load(Order.new, "OrderStreamHere")
60
- ```
61
- EOW
62
- @loaded_from_stream_name = stream_name
63
- Repository.new(event_store).load(self, stream_name)
55
+ def unpublished_events
56
+ @unpublished_events.each
57
+ end
64
58
  end
65
59
 
66
- def store(stream_name = loaded_from_stream_name, event_store: default_event_store)
67
- warn <<~EOW
68
- Method `store` on aggregate is deprecated. Use AggregateRoot::Repository instead.
69
- Instead of: `order.store("OrderStreamHere")`
70
- you need to have code:
71
- ```
72
- repository = AggregateRoot::Repository.new
73
- # load and order and execute some operation on it here
74
- repository.store(order, "OrderStreamHere")
75
- ```
76
- EOW
77
- Repository.new(event_store).store(self, stream_name)
60
+ def self.with_default_apply_strategy
61
+ Module.new do
62
+ def self.included(host_class)
63
+ host_class.extend OnDSL
64
+ host_class.include AggregateRoot.with_strategy(->{ DefaultApplyStrategy.new })
65
+ end
66
+ end
78
67
  end
79
68
 
80
- private
81
- attr_reader :loaded_from_stream_name
82
-
83
- def default_event_store
84
- AggregateRoot.configuration.default_event_store
85
- end
69
+ def self.with_strategy(strategy)
70
+ Module.new do
71
+ def self.included(host_class)
72
+ host_class.extend Constructor
73
+ host_class.include AggregateMethods
74
+ end
86
75
 
87
- def unpublished
88
- @unpublished_events ||= []
76
+ define_method :apply_strategy do
77
+ strategy.call
78
+ end
79
+ end
89
80
  end
90
81
 
91
- def apply_strategy
92
- DefaultApplyStrategy.new(on_methods: self.class.on_methods)
82
+ def self.included(host_class)
83
+ host_class.include with_default_apply_strategy
93
84
  end
94
85
  end
@@ -2,13 +2,12 @@ module AggregateRoot
2
2
  MissingHandler = Class.new(StandardError)
3
3
 
4
4
  class DefaultApplyStrategy
5
- def initialize(strict: true, on_methods: {})
5
+ def initialize(strict: true)
6
6
  @strict = strict
7
- @on_methods = on_methods
8
7
  end
9
8
 
10
9
  def call(aggregate, event)
11
- name = handler_name(event)
10
+ name = handler_name(aggregate, event)
12
11
  if aggregate.respond_to?(name, true)
13
12
  aggregate.method(name).call(event)
14
13
  else
@@ -18,16 +17,16 @@ module AggregateRoot
18
17
 
19
18
  private
20
19
 
21
- def handler_name(event)
22
- on_methods.fetch(event.class) { handler_name_by_class(event.class) }
20
+ def handler_name(aggregate, event)
21
+ aggregate.class.on_methods.fetch(event.type) { handler_name_by_type(event.type) }
23
22
  end
24
23
 
25
- def handler_name_by_class(event_class)
26
- "apply_#{Transform.to_snake_case(class_name(event_class))}"
24
+ def handler_name_by_type(event_type)
25
+ "apply_#{Transform.to_snake_case(event_type(event_type))}"
27
26
  end
28
27
 
29
- def class_name(event_class)
30
- event_class.name.split("::").last
28
+ def event_type(event_type)
29
+ event_type.split(%r{::|\.}).last
31
30
  end
32
31
 
33
32
  private
@@ -0,0 +1,34 @@
1
+ module AggregateRoot
2
+ class InstrumentedRepository
3
+ def initialize(repository, instrumentation)
4
+ @repository = repository
5
+ @instrumentation = instrumentation
6
+ end
7
+
8
+ def load(aggregate, stream_name)
9
+ instrumentation.instrument("load.repository.aggregate_root",
10
+ aggregate: aggregate,
11
+ stream: stream_name) do
12
+ repository.load(aggregate, stream_name)
13
+ end
14
+ end
15
+
16
+ def store(aggregate, stream_name)
17
+ instrumentation.instrument("store.repository.aggregate_root",
18
+ aggregate: aggregate,
19
+ version: aggregate.version,
20
+ stored_events: aggregate.unpublished_events.to_a,
21
+ stream: stream_name) do
22
+ repository.store(aggregate, stream_name)
23
+ end
24
+ end
25
+
26
+ def with_aggregate(aggregate, stream_name, &block)
27
+ block.call(load(aggregate, stream_name))
28
+ store(aggregate, stream_name)
29
+ end
30
+
31
+ private
32
+ attr_reader :instrumentation, :repository
33
+ end
34
+ end
@@ -29,4 +29,4 @@ module AggregateRoot
29
29
  AggregateRoot.configuration.default_event_store
30
30
  end
31
31
  end
32
- end
32
+ end
@@ -1,3 +1,3 @@
1
1
  module AggregateRoot
2
- VERSION = "0.39.0"
2
+ VERSION = "0.40.0"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: aggregate_root
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.39.0
4
+ version: 0.40.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Arkency
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2019-04-24 00:00:00.000000000 Z
11
+ date: 2019-06-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: ruby_event_store
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - '='
18
18
  - !ruby/object:Gem::Version
19
- version: 0.39.0
19
+ version: 0.40.0
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - '='
25
25
  - !ruby/object:Gem::Version
26
- version: 0.39.0
26
+ version: 0.40.0
27
27
  description: Event sourced (with Rails Event Store) aggregate root implementation
28
28
  email:
29
29
  - dev@arkency.com
@@ -39,6 +39,7 @@ files:
39
39
  - lib/aggregate_root.rb
40
40
  - lib/aggregate_root/configuration.rb
41
41
  - lib/aggregate_root/default_apply_strategy.rb
42
+ - lib/aggregate_root/instrumented_repository.rb
42
43
  - lib/aggregate_root/repository.rb
43
44
  - lib/aggregate_root/transform.rb
44
45
  - lib/aggregate_root/version.rb
@@ -65,7 +66,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
65
66
  - !ruby/object:Gem::Version
66
67
  version: '0'
67
68
  requirements: []
68
- rubygems_version: 3.0.3
69
+ rubygems_version: 3.0.1
69
70
  signing_key:
70
71
  specification_version: 4
71
72
  summary: Event sourced (with Rails Event Store) aggregate root implementation