simple_event_sourcing 0.1.0 → 0.2.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: 27655968339ee4735cea0e938d618b2892d0a85e276e279ad6651d44c89726c7
4
- data.tar.gz: d192ef1f40ff278c102658df21d8b8160bc1c0b336b6b4f70111d21554b63647
3
+ metadata.gz: 8c8f96d29fae329c09e8001a2ce8ab34e725ba76095d61e7927acf42321be8c2
4
+ data.tar.gz: 69fc9bde337b95d771f4ca23a15f7eedc0b40d0e39df082b39272e96c4ecf88a
5
5
  SHA512:
6
- metadata.gz: 97f34f53c14960df110797f2bc08ae9b7090ef57d55a500aee85dee982b31f9e174509b53c4f851e0a88b8bed54d7805bbc7540fef4c73778837c1cbcce59c15
7
- data.tar.gz: 3090508f627ce2eb0ebae39f025876b0299c662744fe54cf549bd734299237c75a804c40d6ddb218cc89b77581db81a5d50e770192569bbc24056f9478d0455e
6
+ metadata.gz: 48671ba2bc1b7b37e7130622f87f7d519bafa91f9e38e1f26f3b346d14f60354b92e9cabfe1c8005f309cde15204ded274095867470f3800b7298e5ee7ff7104
7
+ data.tar.gz: ca37c5f86523fb2d3e28a6eedbe9f3f9ea9999940cba3d05daf616c18e7178e985e97df83f88a3860a6d019a42b778753a23252e6ac91bbc1ae3f0e0a2b37358
data/.gitignore CHANGED
@@ -10,3 +10,4 @@
10
10
 
11
11
  # rspec failure tracking
12
12
  .rspec_status
13
+ *.gem
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- simple_event_sourcing (0.1.0)
4
+ simple_event_sourcing (0.2.0)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
data/README.md CHANGED
@@ -1,8 +1,17 @@
1
1
  # EventSourcing
2
2
 
3
- Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/simple_event_sourcing`. To experiment with that code, run `bin/console` for an interactive prompt.
3
+ The fundamental idea of Event Sourcing is that of ensuring every change to the state of an application is captured in an event object, and that these event objects are themselves stored in the sequence they were applied for the same lifetime as the application state itself.
4
4
 
5
- TODO: Delete this and the text above, and describe your gem
5
+ Martin Fowler , https://martinfowler.com/eaaDev/EventSourcing.html
6
+
7
+ This gem provides a simple way for add events sourcing related behaviour to your models class.
8
+
9
+ Base classes
10
+
11
+ - AggregateRoot
12
+ - Event
13
+ - EventStream
14
+ - EventPublisher
6
15
 
7
16
  ## Installation
8
17
 
@@ -22,13 +31,86 @@ Or install it yourself as:
22
31
 
23
32
  ## Usage
24
33
 
25
- TODO: Write usage instructions here
34
+ Here an example of use:
35
+
36
+ ```ruby
37
+ class Employee
38
+
39
+ include SimpleEventSourcing::AggregateRoot
40
+
41
+ attr_reader :name, :title, :salary
42
+
43
+ def initialize(args = nil )
44
+ super
45
+ unless args.nil?
46
+ apply_record_event NewEmployeeIsHiredEvent.new(@aggregate_id, args[:name], args[:title], args[:salary] )
47
+ end
48
+ end
49
+
50
+ def salary=(new_salary)
51
+ apply_record_event SalaryHasChangedEvent.new(@aggregate_id, new_salary)
52
+ end
53
+
54
+ def apply_new_employee_is_hired_event(event)
55
+ @name = event.name
56
+ @title = event.title
57
+ @salary = event.salary
58
+ end
59
+
60
+ def apply_salary_has_changed_event(event)
61
+ @salary = event.new_salary
62
+ end
63
+
64
+ def save
65
+ # Persist the entity
66
+ publish_events { |event| SimpleEventSourcing::EventPublisher.publish(event) }
67
+ end
68
+
69
+ end
70
+ ```
71
+
72
+ Firts you mus add behaviour including the AggregateRoot module
73
+
74
+ ```ruby
75
+ include SimpleEventSourcing::AggregateRoot
76
+ ```
77
+
78
+ After that all domain event must be applied and recorded
79
+
80
+ ```ruby
81
+ apply_record_event SalaryHasChangedEvent.new(@aggregate_id, new_salary)
82
+ ```
83
+
84
+ You must create your own events and a event stream
26
85
 
27
- ## Development
86
+ ```ruby
87
+ class EmployeeStreamEvents < SimpleEventSourcing::StreamEvents
88
+ def get_aggregate_class
89
+ Employee
90
+ end
91
+ end
92
+
93
+ class SalaryHasChangedEvent < SimpleEventSourcing::Event
94
+ attr_reader :aggregate_id, :new_salary
95
+
96
+ def initialize(aggregate_id, new_salary)
97
+ @aggregate_id = aggregate_id
98
+ @new_salary = new_salary
99
+ super()
100
+ end
101
+ end
102
+ ```
28
103
 
29
- After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
104
+ Once you persist the entity you must publish all recorded events.
105
+
106
+ ```ruby
107
+ def save
108
+ # Persist the entity
109
+ publish_events { |event| SimpleEventSourcing::EventPublisher.publish(event) }
110
+ end
111
+ ```
30
112
 
31
- To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
113
+ Happy coding!
32
114
 
33
115
  ## Contributing
34
116
 
@@ -1,104 +1,9 @@
1
1
  require 'simple_event_sourcing/version'
2
- require 'securerandom'
3
- require 'facets'
4
2
 
5
- module SimpleEventSourcing
6
- class Event
7
- attr_reader :occurred_on
8
-
9
- def initialize
10
- @occurred_on ||= Time.new
11
- end
12
- end
13
-
14
- class StreamEvents < Array
15
- attr_reader :aggregate_id
16
-
17
- def initialize(aggregate_id)
18
- @aggregate_id = aggregate_id
19
- end
20
-
21
- def get_aggregate
22
- aggregate = get_aggregate_class.create_from_agrregate_id @aggregate_id
23
- each { |event| aggregate.apply_record_event event }
24
- aggregate
25
- end
26
-
27
- def get_aggregate_class
28
- raise StandardError('Method must be implemented')
29
- end
30
- end
31
-
32
- module EventPublisher
33
- @@subscribers = []
34
-
35
- def self.add_subscriber(subscriber)
36
- @@subscribers << subscriber
37
- end
38
-
39
- def self.delete_subscriber(subscriber)
40
- @@subscribers.delete(subscriber)
41
- end
42
-
43
- def self.get_subscribers
44
- @@subscribers
45
- end
46
3
 
47
- def self.publish(event)
48
- @@subscribers.each { |subscriber| subscriber.handle(event) if subscriber.is_subscribet_to? event }
49
- end
50
- end
4
+ require_relative 'simple_event_sourcing/aggregate_root/aggregate_root'
5
+ require_relative 'simple_event_sourcing/events/events'
51
6
 
52
- module AggregateRoot
53
- def self.included(o)
54
- o.extend(ClassMethods)
55
- end
56
-
57
- attr_accessor :aggregate_id
58
- attr_reader :events
59
-
60
- def initialize(_args = nil)
61
- @events = []
62
- @aggregate_id ||= SecureRandom.uuid
63
- end
64
-
65
- def have_changed?
66
- (@events.count > 0)
67
- end
68
-
69
- def publish_events
70
- @events.each do |event|
71
- yield(event)
72
- end
73
- clear_events
74
- end
75
-
76
- def apply_record_event(event)
77
- apply_event event
78
- record_event event
79
- end
80
-
81
- private
82
-
83
- def record_event(event)
84
- @events << event
85
- end
86
-
87
- def clear_events
88
- @events = []
89
- end
90
-
91
- def apply_event(event)
92
- method = 'apply_' + event.class.name.snakecase
93
- send(method, event)
94
- end
7
+ module SimpleEventSourcing
95
8
 
96
- module ClassMethods
97
- def create_from_agrregate_id(id)
98
- aggregate = new
99
- aggregate.aggregate_id = id
100
- aggregate
101
- end
102
- end
103
- end
104
9
  end
@@ -0,0 +1,59 @@
1
+ require 'securerandom'
2
+ require 'facets'
3
+
4
+ module SimpleEventSourcing
5
+ module AggregateRoot
6
+
7
+ attr_accessor :aggregate_id
8
+ attr_reader :events
9
+
10
+ def initialize(_args = nil)
11
+ @events = []
12
+ @aggregate_id ||= SecureRandom.uuid
13
+ end
14
+
15
+ def have_changed?
16
+ (@events.count > 0)
17
+ end
18
+
19
+ def publish_events
20
+ @events.each do |event|
21
+ yield(event)
22
+ end
23
+ clear_events
24
+ end
25
+
26
+ def apply_record_event(event)
27
+ apply_event event
28
+ record_event event
29
+ end
30
+
31
+ def self.included(o)
32
+ o.extend(ClassMethods)
33
+ end
34
+
35
+ module ClassMethods
36
+ def create_from_agrregate_id(id)
37
+ aggregate = new
38
+ aggregate.aggregate_id = id
39
+ aggregate
40
+ end
41
+ end
42
+
43
+ private
44
+
45
+ def record_event(event)
46
+ @events << event
47
+ end
48
+
49
+ def clear_events
50
+ @events = []
51
+ end
52
+
53
+ def apply_event(event)
54
+ method = 'apply_' + event.class.name.snakecase
55
+ send(method, event)
56
+ end
57
+
58
+ end
59
+ end
@@ -0,0 +1,48 @@
1
+ module SimpleEventSourcing
2
+
3
+ class Event
4
+ attr_reader :occurred_on
5
+
6
+ def initialize
7
+ @occurred_on ||= Time.new
8
+ end
9
+ end
10
+
11
+ class StreamEvents < Array
12
+ attr_reader :aggregate_id
13
+
14
+ def initialize(aggregate_id)
15
+ @aggregate_id = aggregate_id
16
+ end
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
23
+
24
+ def get_aggregate_class
25
+ raise StandardError('Method must be implemented')
26
+ end
27
+ end
28
+
29
+ module EventPublisher
30
+ @@subscribers = []
31
+
32
+ def self.add_subscriber(subscriber)
33
+ @@subscribers << subscriber
34
+ end
35
+
36
+ def self.delete_subscriber(subscriber)
37
+ @@subscribers.delete(subscriber)
38
+ end
39
+
40
+ def self.get_subscribers
41
+ @@subscribers
42
+ end
43
+
44
+ def self.publish(event)
45
+ @@subscribers.each { |subscriber| subscriber.handle(event) if subscriber.is_subscribet_to? event }
46
+ end
47
+ end
48
+ end
@@ -1,3 +1,3 @@
1
1
  module SimpleEventSourcing
2
- VERSION = "0.1.0"
2
+ VERSION = "0.2.0"
3
3
  end
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.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Manel
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2018-04-20 00:00:00.000000000 Z
11
+ date: 2018-04-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -106,6 +106,8 @@ files:
106
106
  - example/employee_subscribers.rb
107
107
  - example/main.rb
108
108
  - lib/simple_event_sourcing.rb
109
+ - lib/simple_event_sourcing/aggregate_root/aggregate_root.rb
110
+ - lib/simple_event_sourcing/events/events.rb
109
111
  - lib/simple_event_sourcing/version.rb
110
112
  - run.sh
111
113
  - simple_event_sourcing.gemspec