simple_event_sourcing 0.3.0 → 0.4.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: 666d470eb4b8fadd4728c3bd093e216b6454272d23a3f2891fef63657855a270
4
- data.tar.gz: 828c08776a5200bd236783f0d911b25ac4283ae87d628f102e61554d0c61089e
3
+ metadata.gz: 0611f1925717d9e7186c6afd3cb564ed9224969bffd3b681e20a503f6326749b
4
+ data.tar.gz: 8e9c67af00a6782f5097d4aad1892925bd9c20245d3c78e0ebebe28db44cdffc
5
5
  SHA512:
6
- metadata.gz: d0b8fae3aac98197e3cbcf73f44ed374208239166cb631c952844196abdea07b81fcddbdb2cd03d604481f6d0859f4390384f359e0cc6cdf84df6c4c33df114f
7
- data.tar.gz: 888f20ab00ebe27210b225760885cc35e8f654df4050068ad5979e33f4490e3451ed59325be12b6c64b96a774f840ac0634aa4d36dc9e9f07ce938a425bc1717
6
+ metadata.gz: 1f162f575634be6a4a5aaaa935afa736c7e9059507bd8b054489ff07e5d18fdd8900124287f6eedb6423c86bfd1b5fd27de41dbb28caf5de72a46834248f91f7
7
+ data.tar.gz: 0a7c0bcb4a586321420781093f3630d88f882d37b1d8d3b257c44f067838f1c3af55322b73e0faadd6d261afbde17d56d92ad7a6845b82ff1059beda96b86b3a
data/.gitignore CHANGED
File without changes
data/.rspec CHANGED
File without changes
data/.simplecov CHANGED
File without changes
data/.travis.yml CHANGED
File without changes
data/CODE_OF_CONDUCT.md CHANGED
File without changes
data/Dockerfile CHANGED
File without changes
data/Gemfile CHANGED
File without changes
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- simple_event_sourcing (0.3.0)
4
+ simple_event_sourcing (0.4.0)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
data/LICENSE.txt CHANGED
File without changes
data/README.md CHANGED
@@ -9,9 +9,10 @@ This gem provides a simple way for add events sourcing related behaviour to your
9
9
  Base classes
10
10
 
11
11
  - AggregateRoot
12
+ - UUID Id
12
13
  - Event
13
14
  - EventStream
14
- - EventPublisher
15
+ - EventDispatcher
15
16
 
16
17
  ## Installation
17
18
 
@@ -63,7 +64,7 @@ class Employee
63
64
 
64
65
  def save
65
66
  # Persist the entity
66
- publish_events { |event| SimpleEventSourcing::EventPublisher.publish(event) }
67
+ publish_events { |event| SimpleEventSourcing::Events::EventDispatcher.publish(event) }
67
68
  end
68
69
 
69
70
  end
@@ -78,7 +79,7 @@ First, you must add behaviour including the AggregateRoot module
78
79
  You must create your own domain events and a event stream
79
80
 
80
81
  ```ruby
81
- class EmployeeStreamEvents < SimpleEventSourcing::StreamEvents
82
+ class EmployeeStreamEvents < SimpleEventSourcing::AggregateRoot::History
82
83
  def get_aggregate_class
83
84
  Employee
84
85
  end
@@ -109,14 +110,12 @@ on SalaryHasChangedEvent do |event|
109
110
  end
110
111
  ```
111
112
 
112
-
113
-
114
113
  Once you persist the entity you must publish all recorded events.
115
114
 
116
115
  ```ruby
117
116
  def save
118
117
  # Persist the entity
119
- publish_events { |event| SimpleEventSourcing::EventPublisher.publish(event) }
118
+ publish_events { |event| SimpleEventSourcing::EventDispatcher.publish(event) }
120
119
  end
121
120
  ```
122
121
 
data/Rakefile CHANGED
File without changes
data/docker-compose.yml CHANGED
File without changes
data/example/employee.rb CHANGED
@@ -1,13 +1,13 @@
1
1
  require_relative '../lib/simple_event_sourcing'
2
2
 
3
- class EmployeeStreamEvents < SimpleEventSourcing::StreamEvents
3
+ class EmployeeStreamEvents < SimpleEventSourcing::AggregateRoot::History
4
4
  def get_aggregate_class
5
5
  Employee
6
6
  end
7
7
  end
8
8
 
9
9
 
10
- class NewEmployeeIsHiredEvent < SimpleEventSourcing::Event
10
+ class NewEmployeeIsHiredEvent < SimpleEventSourcing::Events::Event
11
11
  attr_reader :name, :title,:salary
12
12
 
13
13
  def initialize(aggregate_id, name, title, salary)
@@ -19,7 +19,7 @@ class NewEmployeeIsHiredEvent < SimpleEventSourcing::Event
19
19
  end
20
20
  end
21
21
 
22
- class SalaryHasChangedEvent < SimpleEventSourcing::Event
22
+ class SalaryHasChangedEvent < SimpleEventSourcing::Events::Event
23
23
  attr_reader :aggregate_id, :new_salary
24
24
 
25
25
  def initialize(aggregate_id, new_salary)
@@ -29,7 +29,7 @@ class SalaryHasChangedEvent < SimpleEventSourcing::Event
29
29
  end
30
30
  end
31
31
 
32
- class CongratulateEmployeeSubscriber < SimpleEventSourcing::EventSubscriber
32
+ class CongratulateEmployeeSubscriber < SimpleEventSourcing::Events::EventSubscriber
33
33
 
34
34
  def is_subscribet_to?(event)
35
35
  event.class == SalaryHasChangedEvent
@@ -44,7 +44,7 @@ end
44
44
 
45
45
  class Employee
46
46
 
47
- include SimpleEventSourcing::AggregateRoot
47
+ include SimpleEventSourcing::AggregateRoot::Base
48
48
 
49
49
  attr_reader :name, :title, :salary
50
50
 
@@ -71,7 +71,7 @@ class Employee
71
71
 
72
72
  def save
73
73
  # Persist the entity
74
- publish_events { |event| SimpleEventSourcing::EventPublisher.publish(event) }
74
+ publish_events { |event| SimpleEventSourcing::Events::EventDispatcher.publish(event) }
75
75
  end
76
76
 
77
77
  end
data/example/main.rb CHANGED
@@ -1,7 +1,12 @@
1
+
2
+ unless $LOAD_PATH.include?(File.expand_path(File.dirname(__FILE__)+'/../lib'))
3
+ $LOAD_PATH.unshift(File.expand_path(File.dirname(__FILE__)+'/../lib'))
4
+ end
5
+
1
6
  require 'simple_event_sourcing'
2
- require_relative 'employee'
7
+ require_relative './employee'
3
8
 
4
- SimpleEventSourcing::EventPublisher.add_subscriber(CongratulateEmployeeSubscriber.new)
9
+ SimpleEventSourcing::Events::EventDispatcher.add_subscriber(CongratulateEmployeeSubscriber.new)
5
10
 
6
11
  fred = Employee.new(name: "Fred Flintstone", title: "Crane Operator", salary: 30000.0)
7
12
  fred.salary=35000.0
@@ -0,0 +1,75 @@
1
+ module SimpleEventSourcing
2
+ module AggregateRoot
3
+
4
+ module Base
5
+
6
+ attr_accessor :aggregate_id
7
+ attr_reader :events
8
+
9
+ def initialize(_args = nil)
10
+ @events = []
11
+ @aggregate_id ||= SimpleEventSourcing::Id::UUIDId.generate
12
+ end
13
+
14
+ def have_changed?
15
+ (@events.count > 0)
16
+ end
17
+
18
+ def publish_events
19
+ @events.each do |event|
20
+ yield(event)
21
+ end
22
+ clear_events
23
+ end
24
+
25
+ def apply_record_event(event)
26
+ handle_message(event)
27
+ record_event event
28
+ end
29
+
30
+ def handle_message(message)
31
+ handler = self.class.message_mapping[message.class]
32
+ self.instance_exec(message, &handler) if handler
33
+ end
34
+
35
+ def self.included(o)
36
+ o.extend(ClassMethods)
37
+ end
38
+
39
+ module ClassMethods
40
+ def create_from_agrregate_id(id)
41
+ aggregate = new
42
+ aggregate.aggregate_id = id
43
+ aggregate
44
+ end
45
+ def on(*message_classes, &block)
46
+ message_classes.each { |message_class| message_mapping[message_class] = block }
47
+ end
48
+
49
+ def message_mapping
50
+ @message_mapping ||= {}
51
+ end
52
+
53
+ def handles_message?(message)
54
+ message_mapping.keys.include? message.class
55
+ end
56
+ end
57
+
58
+ private
59
+
60
+ def record_event(event)
61
+ @events << event
62
+ end
63
+
64
+ def clear_events
65
+ @events = []
66
+ end
67
+
68
+ def apply_event(event)
69
+ handle_message(event)
70
+ #method = 'apply_' + event.class.name.snakecase
71
+ #send(method, event)
72
+ end
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,21 @@
1
+ module SimpleEventSourcing
2
+ module AggregateRoot
3
+ class History < Array
4
+ attr_reader :aggregate_id
5
+
6
+ def initialize(aggregate_id)
7
+ @aggregate_id = aggregate_id
8
+ end
9
+
10
+ def get_aggregate
11
+ aggregate = get_aggregate_class.create_from_agrregate_id @aggregate_id
12
+ each { |event| aggregate.apply_record_event event }
13
+ aggregate
14
+ end
15
+
16
+ def get_aggregate_class
17
+ raise StandardError('Method must be implemented')
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,54 @@
1
+ require 'securerandom'
2
+
3
+ module SimpleEventSourcing
4
+
5
+ module Id
6
+
7
+ class BaseId
8
+ def initialize(value)
9
+ @value = value
10
+ end
11
+
12
+ def id
13
+ @value
14
+ end
15
+
16
+ def to_s
17
+ @value
18
+ end
19
+
20
+ def ==(other_id)
21
+ self.class == other_id.class && @value == other_id.id
22
+ end
23
+
24
+ alias eql? ==
25
+
26
+ end
27
+
28
+ class UUIDId < BaseId
29
+ def initialize(value)
30
+ raise UUIDValidationError unless valid? value
31
+ super(value)
32
+ end
33
+
34
+ def self.generate
35
+ new SecureRandom.uuid
36
+ end
37
+
38
+ private
39
+
40
+ def valid?(uuid)
41
+ uuid_regex = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/
42
+ return true if uuid_regex =~ uuid.to_s.downcase
43
+ return false
44
+ end
45
+ end
46
+
47
+ class UUIDValidationError < StandardError
48
+ def initialize(msg="Value is not a valid UUID")
49
+ super
50
+ end
51
+ end
52
+
53
+ end
54
+ end
@@ -1,60 +1,56 @@
1
1
  module SimpleEventSourcing
2
+ module Events
2
3
 
3
- class Event
4
- attr_reader :occurred_on
4
+ class Event
5
+ attr_reader :occured_on
5
6
 
6
- def initialize
7
- @occurred_on ||= Time.new
7
+ def initialize
8
+ @occured_on ||= Time.new
9
+ end
8
10
  end
9
- end
10
11
 
11
- class StreamEvents < Array
12
- attr_reader :aggregate_id
12
+ class EventSubscriber
13
13
 
14
- def initialize(aggregate_id)
15
- @aggregate_id = aggregate_id
16
- end
14
+ def is_subscribet_to?(event)
15
+ raise StandardError "Method not implemented"
16
+ end
17
17
 
18
- def get_aggregate
19
- aggregate = get_aggregate_class.create_from_agrregate_id @aggregate_id
20
- each { |event| aggregate.apply_record_event event }
21
- aggregate
22
- end
18
+ def check(event)
19
+ raise EventIsNotAllowedToBeHandled unless is_subscribet_to? event
20
+ end
23
21
 
24
- def get_aggregate_class
25
- raise StandardError('Method must be implemented')
26
- end
27
- end
22
+ def handle_event(event)
23
+ raise StandardError "Method not implemented"
24
+ end
28
25
 
29
- class EventSubscriber
26
+ def handle(event)
27
+ check event
28
+ handle_event event
29
+ end
30
30
 
31
- def is_subscribet_to?(event)
32
- raise StandardError "Method not implemented"
33
31
  end
34
32
 
35
- def handle(event)
36
- raise StandardError "Method not implemented"
37
- end
38
- end
33
+ class EventIsNotAllowedToBeHandled < StandardError; end
39
34
 
35
+ module EventDispatcher
36
+ @@subscribers = []
40
37
 
41
- module EventPublisher
42
- @@subscribers = []
38
+ def self.add_subscriber(subscriber)
39
+ @@subscribers << subscriber
40
+ end
43
41
 
44
- def self.add_subscriber(subscriber)
45
- @@subscribers << subscriber
46
- end
42
+ def self.delete_subscriber(subscriber)
43
+ @@subscribers.delete(subscriber)
44
+ end
47
45
 
48
- def self.delete_subscriber(subscriber)
49
- @@subscribers.delete(subscriber)
50
- end
46
+ def self.get_subscribers
47
+ @@subscribers
48
+ end
51
49
 
52
- def self.get_subscribers
53
- @@subscribers
50
+ def self.publish(event)
51
+ @@subscribers.each { |subscriber| subscriber.handle(event) if subscriber.is_subscribet_to? event }
52
+ end
54
53
  end
55
54
 
56
- def self.publish(event)
57
- @@subscribers.each { |subscriber| subscriber.handle(event) if subscriber.is_subscribet_to? event }
58
- end
59
55
  end
60
56
  end
@@ -1,3 +1,3 @@
1
1
  module SimpleEventSourcing
2
- VERSION = "0.3.0"
2
+ VERSION = "0.4.0"
3
3
  end
@@ -1,8 +1,6 @@
1
1
  require 'simple_event_sourcing/version'
2
2
 
3
- require_relative 'simple_event_sourcing/aggregate_root/aggregate_root'
4
- require_relative 'simple_event_sourcing/events/events'
5
-
6
- module SimpleEventSourcing
7
-
8
- end
3
+ require 'simple_event_sourcing/aggregate_root/id'
4
+ require 'simple_event_sourcing/aggregate_root/base'
5
+ require 'simple_event_sourcing/aggregate_root/history'
6
+ require 'simple_event_sourcing/events/events'
data/run.sh CHANGED
File without changes
File without changes
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: simple_event_sourcing
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Manuel López Torrent
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2018-04-22 00:00:00.000000000 Z
11
+ date: 2018-04-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -105,8 +105,9 @@ files:
105
105
  - example/employee.rb
106
106
  - example/main.rb
107
107
  - lib/simple_event_sourcing.rb
108
- - lib/simple_event_sourcing/aggregate_root/aggregate_root.rb
109
- - lib/simple_event_sourcing/aggregate_root/self_applier.rb
108
+ - lib/simple_event_sourcing/aggregate_root/base.rb
109
+ - lib/simple_event_sourcing/aggregate_root/history.rb
110
+ - lib/simple_event_sourcing/aggregate_root/id.rb
110
111
  - lib/simple_event_sourcing/events/events.rb
111
112
  - lib/simple_event_sourcing/version.rb
112
113
  - run.sh
@@ -131,7 +132,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
131
132
  version: '0'
132
133
  requirements: []
133
134
  rubyforge_project:
134
- rubygems_version: 2.7.2
135
+ rubygems_version: 2.7.6
135
136
  signing_key:
136
137
  specification_version: 4
137
138
  summary: This gem provides a simple way for add events sourcing related behaviour
@@ -1,62 +0,0 @@
1
- require 'securerandom'
2
- require 'facets'
3
-
4
- require_relative 'self_applier'
5
-
6
- module SimpleEventSourcing
7
- module AggregateRoot
8
-
9
- attr_accessor :aggregate_id
10
- attr_reader :events
11
-
12
- def initialize(_args = nil)
13
- @events = []
14
- @aggregate_id ||= SecureRandom.uuid
15
- end
16
-
17
- def have_changed?
18
- (@events.count > 0)
19
- end
20
-
21
- def publish_events
22
- @events.each do |event|
23
- yield(event)
24
- end
25
- clear_events
26
- end
27
-
28
- def apply_record_event(event)
29
- handle_message(event)
30
- record_event event
31
- end
32
-
33
- def self.included(o)
34
- o.extend(ClassMethods)
35
- end
36
-
37
- module ClassMethods
38
- def create_from_agrregate_id(id)
39
- aggregate = new
40
- aggregate.aggregate_id = id
41
- aggregate
42
- end
43
- end
44
-
45
- private
46
-
47
- def record_event(event)
48
- @events << event
49
- end
50
-
51
- def clear_events
52
- @events = []
53
- end
54
-
55
- def apply_event(event)
56
- handle_message(event)
57
- #method = 'apply_' + event.class.name.snakecase
58
- #send(method, event)
59
- end
60
-
61
- end
62
- end
@@ -1,41 +0,0 @@
1
- module SimpleEventSourcing
2
- module AggregateRoot
3
- ##
4
- # Creates ability to use DSL like:
5
- # class MyEventHandler < Sequent::Core::BaseEventHandler
6
- #
7
- # on MyEvent do |event|
8
- # do_some_logic
9
- # end
10
- # end
11
- #
12
- # You typically do not need to include this module in your classes. If you extend from
13
- # Sequent::Core::AggregateRoot, Sequent::Core::Projector, Sequent::Core::Workflow or Sequent::Core::BaseCommandHandler
14
- # you will get this functionality for free.
15
- #
16
-
17
- module ClassMethods
18
- def on(*message_classes, &block)
19
- message_classes.each { |message_class| message_mapping[message_class] = block }
20
- end
21
-
22
- def message_mapping
23
- @message_mapping ||= {}
24
- end
25
-
26
- def handles_message?(message)
27
- message_mapping.keys.include? message.class
28
- end
29
- end
30
-
31
- def self.included(host_class)
32
- host_class.extend(ClassMethods)
33
- end
34
-
35
- def handle_message(message)
36
- handler = self.class.message_mapping[message.class]
37
- self.instance_exec(message, &handler) if handler
38
- end
39
- end
40
-
41
- end