event_sorcerer 0.0.4 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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