event_sorcerer 0.0.4 → 0.1.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
  SHA1:
3
- metadata.gz: 79a912a68e2870c219ada44383c9dc31094153ed
4
- data.tar.gz: a06601573292fe7dff5992c019c53123f1f9876d
3
+ metadata.gz: 58f7bb946b104e7e64a07a78e3bcb5271295aae6
4
+ data.tar.gz: b6fe6643e1f836722cdb917d24be90af205352a3
5
5
  SHA512:
6
- metadata.gz: 5996d9ee1b0d9231bde34f0195be5dd1b5ad6f57a129f0dae508960fe1f9e18fa522cd6d368f7ca21149ba2c0350fb44d8b77371c5904cfb0e3c15fe2231d49f
7
- data.tar.gz: e46130b30ffb009d7141dca1a358c4233467b9d796e5e40da343a880244897032d0699037ab00e4cff759f1482a4a10766697e85a8de378bb46e9baee96d675b
6
+ metadata.gz: 31129950df220d9672037b3bf205a4f3450e0ee81735024736058f40b12a1e00ba209d9cadec8f2003f66e281ae7fc724b0d99b668e3d0ab2e8969239061a624
7
+ data.tar.gz: 798db082c7343649a0c529a1ec3d91880cf00af0e9b87785d7f4277912f2b76d0154cccc42bb28a64c7bd2e4e6a1286a46c6233b458f691b7975e6eb77fa691c
data/README.md CHANGED
@@ -2,6 +2,8 @@
2
2
 
3
3
  Generic event-sourcing scaffold.
4
4
 
5
+ [![Code Climate](https://codeclimate.com/github/SebastianEdwards/event_sorcerer/badges/gpa.svg)](https://codeclimate.com/github/SebastianEdwards/event_sorcerer)
6
+
5
7
  ## Installation
6
8
 
7
9
  Add this line to your application's Gemfile:
@@ -8,6 +8,7 @@ require 'event_sorcerer/argument_hashifier'
8
8
  require 'event_sorcerer/event'
9
9
  require 'event_sorcerer/event_applicator'
10
10
  require 'event_sorcerer/event_store'
11
+ require 'event_sorcerer/event_stream'
11
12
  require 'event_sorcerer/message_bus'
12
13
  require 'event_sorcerer/no_unit_of_work'
13
14
  require 'event_sorcerer/unit_of_work'
@@ -15,7 +15,7 @@ module EventSorcerer
15
15
  base.extend(ClassMethods)
16
16
  base.class.extend(Forwardable)
17
17
  base.class.send :def_delegators, :EventSorcerer, :event_store,
18
- :unit_of_work
18
+ :unit_of_work
19
19
  end
20
20
 
21
21
  # Public: Class methods to be extended onto the including class.
@@ -24,7 +24,11 @@ module EventSorcerer
24
24
  #
25
25
  # Returns an Array of AggregateProxy objects.
26
26
  def all
27
- event_store.get_ids_for_type(self.name).map { |id| find(id) }
27
+ with_all_loaders_for_type do |loaders|
28
+ loaders.map(&:load).each do |aggregate|
29
+ unit_of_work.store_aggregate(aggregate)
30
+ end
31
+ end
28
32
  end
29
33
 
30
34
  # Public: An array of symbols representing the names of the methods which
@@ -64,8 +68,10 @@ module EventSorcerer
64
68
  return unit_of_work.fetch_aggregate(id)
65
69
  end
66
70
 
67
- AggregateLoader.new(self, id).load.tap do |aggregate|
68
- unit_of_work.store_aggregate(aggregate)
71
+ with_loader_for_id(id) do |loader|
72
+ loader.load.tap do |aggregate|
73
+ unit_of_work.store_aggregate(aggregate)
74
+ end
69
75
  end
70
76
  end
71
77
 
@@ -79,8 +85,10 @@ module EventSorcerer
79
85
  return unit_of_work.fetch_aggregate(id)
80
86
  end
81
87
 
82
- AggregateLoader.new(self, id, false).load.tap do |aggregate|
83
- unit_of_work.store_aggregate(aggregate)
88
+ with_loader_for_id(id, false) do |loader|
89
+ loader.load.tap do |aggregate|
90
+ unit_of_work.store_aggregate(aggregate)
91
+ end
84
92
  end
85
93
  end
86
94
 
@@ -94,6 +102,61 @@ module EventSorcerer
94
102
  unit_of_work.store_aggregate(aggregate)
95
103
  end
96
104
  end
105
+
106
+ private
107
+
108
+ # Private: Grabs the event streams for the aggregate class and yields
109
+ # them to a given block.
110
+ #
111
+ # block - the block to yield the event stream to.
112
+ #
113
+ # Returns the return value of the given block.
114
+ def with_all_event_streams_for_type(&block)
115
+ yield event_store.read_event_streams_for_type(name)
116
+ end
117
+
118
+ # Private: Creates AggregateLoaders for an ID and yields it to a given
119
+ # block.
120
+ #
121
+ # prohibit_new - value of the prohibit_new flag to be passed to loaders.
122
+ # block - the block to yield the event stream to.
123
+ #
124
+ # Returns the return value of the given block.
125
+ def with_all_loaders_for_type(prohibit_new = true, &block)
126
+ with_all_event_streams_for_type do |streams|
127
+ loaders = streams.map do |stream|
128
+ AggregateLoader.new(self, stream.id, stream.events,
129
+ stream.current_version, prohibit_new)
130
+ end
131
+
132
+ yield loaders
133
+ end
134
+ end
135
+
136
+ # Private: Grabs the event stream for an ID and yields it to a given
137
+ # block.
138
+ #
139
+ # id - the ID of the aggregate to get the event stream for.
140
+ # block - the block to yield the event stream to.
141
+ #
142
+ # Returns the return value of the given block.
143
+ def with_event_stream_for_id(id, &block)
144
+ yield event_store.read_event_stream(id)
145
+ end
146
+
147
+ # Private: Creates an AggregateLoader for an ID and yields it to a given
148
+ # block.
149
+ #
150
+ # id - the ID of the aggregate to get the event stream for.
151
+ # block - the block to yield the event stream to.
152
+ #
153
+ # Returns the return value of the given block.
154
+ def with_loader_for_id(id, prohibit_new = true, &block)
155
+ with_event_stream_for_id(id) do |stream|
156
+ yield AggregateLoader.new(self, stream.id, stream.events,
157
+ stream.current_version, prohibit_new)
158
+ end
159
+ end
97
160
  end
98
161
  end
99
162
  end
@@ -3,18 +3,17 @@ module EventSorcerer
3
3
  class AggregateLoader
4
4
  extend Forwardable
5
5
 
6
- # Public: Shortcut to access the global event_store.
7
- def_delegators :EventSorcerer, :event_store
8
-
9
6
  # Public: Creates a new AggregateLoader instance.
10
7
  #
11
8
  # klass - class for the aggregate to be loaded.
12
9
  # id - id for the aggregate to be loaded.
13
10
  # prohibit_new - whether or not to raise an error if aggregate not existing.
14
- def initialize(klass, id, prohibit_new = true)
11
+ def initialize(klass, id, events, version, prohibit_new = true)
12
+ @events = events
15
13
  @id = id
16
14
  @klass = klass
17
15
  @prohibit_new = prohibit_new
16
+ @version = version
18
17
  end
19
18
 
20
19
  # Public: Wraps and returns aggregate in a proxy.
@@ -29,6 +28,9 @@ module EventSorcerer
29
28
 
30
29
  private
31
30
 
31
+ # Private: Returns array of Events to hydrate with.
32
+ attr_reader :events
33
+
32
34
  # Private: Returns the id for the aggregate to be loaded.
33
35
  attr_reader :id
34
36
 
@@ -38,6 +40,9 @@ module EventSorcerer
38
40
  # Private: Returns whether new aggregates will be allowed.
39
41
  attr_reader :prohibit_new
40
42
 
43
+ # Private: Returns current version of aggregate.
44
+ attr_reader :version
45
+
41
46
  # Private: Memorizes and returns a new instance of an aggregate. Applies
42
47
  # existing events from the event store.
43
48
  def aggregate
@@ -49,19 +54,12 @@ module EventSorcerer
49
54
  end
50
55
  end
51
56
 
52
- # Private: Memorizes and returns the existing events from the event store.
53
- def events
54
- @events ||= event_store.read_events(id)
55
- end
56
-
57
+ # Private: Checks whether the aggregate is completely new.
58
+ #
59
+ # Returns true if aggregate is new.
60
+ # Returns false if aggregate is not new.
57
61
  def new_aggregate?
58
62
  !version || version == 0
59
63
  end
60
-
61
- # Private: Memorizes and returns the current version number from the event
62
- # store.
63
- def version
64
- @version ||= event_store.get_current_version(id)
65
- end
66
64
  end
67
65
  end
@@ -44,8 +44,8 @@ module EventSorcerer
44
44
  fail NotImplementedError
45
45
  end
46
46
 
47
- # Public: Retrieve the events for a specified aggregate. Should be
48
- # defined in a subclass.
47
+ # Public: Retrieve the events for a specified aggregate. Should be defined
48
+ # in a subclass.
49
49
  #
50
50
  # _aggregate_id - UUID of the aggregate as a String.
51
51
  #
@@ -54,6 +54,39 @@ module EventSorcerer
54
54
  fail NotImplementedError
55
55
  end
56
56
 
57
+ # Public: Retrieve the event stream for a specified aggregate. Should be
58
+ # defined in a subclass.
59
+ #
60
+ # aggregate_id - UUID of the aggregate as a String.
61
+ #
62
+ # Returns an EventStream
63
+ def read_event_stream(aggregate_id)
64
+ EventStream.new(aggregate_id, read_events(aggregate_id),
65
+ get_current_version(aggregate_id))
66
+ end
67
+
68
+ # Public: Retrieve the event stream for all aggregates of a given type.
69
+ # Optionally can be defined in subclass to optimize loading these
70
+ # aggregates with a minimum of external calls.
71
+ #
72
+ # klass - Text representation of aggregate class.
73
+ #
74
+ # Returns an Array.
75
+ def read_event_streams_for_type(klass)
76
+ read_multiple_event_streams get_ids_for_type(klass)
77
+ end
78
+
79
+ # Public: Retrieve the events for multiple aggregates. Optionally can be
80
+ # defined in subclass to optimize loading multiple aggregates with
81
+ # a minimum of external calls.
82
+ #
83
+ # aggregate_ids - Array of UUIDs of the aggregates as Strings.
84
+ #
85
+ # Returns an Array.
86
+ def read_multiple_event_streams(aggregate_ids)
87
+ aggregate_ids.map { |id| read_event_stream id }
88
+ end
89
+
57
90
  # Public: Ensures events appended within the given block are done so
58
91
  # atomically. Should be defined in a subclass.
59
92
  #
@@ -0,0 +1,5 @@
1
+ module EventSorcerer
2
+ # Public: Simple value object representing an event stream.
3
+ class EventStream < Struct.new(:id, :events, :current_version)
4
+ end
5
+ end
@@ -1,4 +1,4 @@
1
1
  # Public: Defines a constant for the current version number.
2
2
  module EventSorcerer
3
- VERSION = '0.0.4'
3
+ VERSION = '0.1.0'
4
4
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: event_sorcerer
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.4
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sebastian Edwards
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-08-06 00:00:00.000000000 Z
11
+ date: 2014-11-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -130,6 +130,7 @@ files:
130
130
  - lib/event_sorcerer/event.rb
131
131
  - lib/event_sorcerer/event_applicator.rb
132
132
  - lib/event_sorcerer/event_store.rb
133
+ - lib/event_sorcerer/event_stream.rb
133
134
  - lib/event_sorcerer/message_bus.rb
134
135
  - lib/event_sorcerer/no_unit_of_work.rb
135
136
  - lib/event_sorcerer/unit_of_work.rb