sequent 4.2.0 → 4.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/sequent/core/aggregate_repository.rb +31 -0
- data/lib/sequent/core/aggregate_root.rb +20 -0
- data/lib/sequent/core/event_store.rb +32 -1
- data/lib/version.rb +1 -1
- metadata +9 -9
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: feea2aeb3dba28570a36615392e4ecc1037bfdfd1c2d667bcc787113e4c7fdba
|
4
|
+
data.tar.gz: 79dc60b21109885a56f3f68cf97185afee5692167f54db1934eaa89dc9d030de
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: bb74d9c6cbb946bab9b00cb2ea73eab80caed4737d12ce2115a6c97348ca0e9452a14280b3d0de9ecba237c201fdd8b2914382751569224c89cae92128d5d3f5
|
7
|
+
data.tar.gz: 5fe084735eb4df8855b8102e68d027ca828a8dd7540d577b6e0a97616bbd22815432e684f20d48d04ad111db962fe935af4bff50afd8ebc7242f5c15f01b97a7
|
@@ -57,6 +57,37 @@ module Sequent
|
|
57
57
|
load_aggregates([aggregate_id], clazz)[0]
|
58
58
|
end
|
59
59
|
|
60
|
+
# Optimised for loading lots of events and ignore snapshot events. To get the correct historical state of an
|
61
|
+
# AggregateRoot it is necessary to be able to ignore snapshots. For a nested AggregateRoot, there will not be a
|
62
|
+
# sequence number known, so a load_until timestamp can be used instead.
|
63
|
+
#
|
64
|
+
# +aggregate_id+ The id of the aggregate to be loaded
|
65
|
+
#
|
66
|
+
# +clazz+ Optional argument that checks if aggregate is of type +clazz+
|
67
|
+
#
|
68
|
+
# +load_until+ Optional argument that defines up until what point in time the AggregateRoot will be rebuilt.
|
69
|
+
def load_aggregate_for_snapshotting(aggregate_id, clazz = nil, load_until: nil)
|
70
|
+
fail ArgumentError, 'aggregate_id is required' if aggregate_id.blank?
|
71
|
+
|
72
|
+
stream = Sequent
|
73
|
+
.configuration
|
74
|
+
.event_store
|
75
|
+
.find_event_stream(aggregate_id)
|
76
|
+
aggregate = Class.const_get(stream.aggregate_type).stream_from_history(stream)
|
77
|
+
|
78
|
+
Sequent
|
79
|
+
.configuration
|
80
|
+
.event_store
|
81
|
+
.stream_events_for_aggregate(aggregate_id, load_until: load_until) do |event_stream|
|
82
|
+
aggregate.stream_from_history(event_stream)
|
83
|
+
end
|
84
|
+
|
85
|
+
if clazz
|
86
|
+
fail TypeError, "#{aggregate.class} is not a #{clazz}" unless aggregate.class <= clazz
|
87
|
+
end
|
88
|
+
aggregate
|
89
|
+
end
|
90
|
+
|
60
91
|
##
|
61
92
|
# Loads multiple aggregates at once.
|
62
93
|
# Returns the ones in the current Unit Of Work otherwise loads it from history.
|
@@ -80,6 +80,26 @@ module Sequent
|
|
80
80
|
events.each { |event| apply_event(event) }
|
81
81
|
end
|
82
82
|
|
83
|
+
def initialize_for_streaming(stream)
|
84
|
+
@uncommitted_events = []
|
85
|
+
@sequence_number = 1
|
86
|
+
@event_stream = stream
|
87
|
+
end
|
88
|
+
|
89
|
+
def stream_from_history(stream_events)
|
90
|
+
_stream, event = stream_events
|
91
|
+
fail 'Empty history' if event.blank?
|
92
|
+
|
93
|
+
@id ||= event.aggregate_id
|
94
|
+
apply_event(event)
|
95
|
+
end
|
96
|
+
|
97
|
+
def self.stream_from_history(stream)
|
98
|
+
aggregate_root = allocate
|
99
|
+
aggregate_root.initialize_for_streaming(stream)
|
100
|
+
aggregate_root
|
101
|
+
end
|
102
|
+
|
83
103
|
def to_s
|
84
104
|
"#{self.class.name}: #{@id}"
|
85
105
|
end
|
@@ -51,7 +51,38 @@ module Sequent
|
|
51
51
|
end
|
52
52
|
|
53
53
|
##
|
54
|
-
# Returns all events for the
|
54
|
+
# Returns all events for the AggregateRoot ordered by sequence_number, disregarding snapshot events.
|
55
|
+
#
|
56
|
+
# This streaming is done in batches to prevent loading many events in memory all at once. A usecase for ignoring
|
57
|
+
# the snapshots is when events of a nested AggregateRoot need to be loaded up until a certain moment in time.
|
58
|
+
#
|
59
|
+
# @param aggregate_id Aggregate id of the AggregateRoot
|
60
|
+
# @param load_until The timestamp up until which you want to built the aggregate. Optional.
|
61
|
+
# @param &block Block that should be passed to handle the batches returned from this method
|
62
|
+
def stream_events_for_aggregate(aggregate_id, load_until: nil, &block)
|
63
|
+
stream = find_event_stream(aggregate_id)
|
64
|
+
fail ArgumentError, 'no stream found for this aggregate' if stream.blank?
|
65
|
+
|
66
|
+
q = Sequent
|
67
|
+
.configuration
|
68
|
+
.event_record_class
|
69
|
+
.where(aggregate_id: aggregate_id)
|
70
|
+
.where.not(event_type: Sequent.configuration.snapshot_event_class.name)
|
71
|
+
.order(:sequence_number)
|
72
|
+
q = q.where('created_at < ?', load_until) if load_until.present?
|
73
|
+
has_events = false
|
74
|
+
|
75
|
+
q.select('event_type, event_json').each_row do |event_hash|
|
76
|
+
has_events = true
|
77
|
+
event = deserialize_event(event_hash)
|
78
|
+
block.call([stream, event])
|
79
|
+
end
|
80
|
+
fail ArgumentError, 'no events for this aggregate' unless has_events
|
81
|
+
end
|
82
|
+
|
83
|
+
##
|
84
|
+
# Returns all events for the aggregate ordered by sequence_number, loading them from the latest snapshot
|
85
|
+
# event onwards, if a snapshot is present
|
55
86
|
#
|
56
87
|
def load_events(aggregate_id)
|
57
88
|
load_events_for_aggregates([aggregate_id])[0]
|
data/lib/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sequent
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 4.
|
4
|
+
version: 4.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Lars Vonk
|
@@ -12,7 +12,7 @@ authors:
|
|
12
12
|
autorequire:
|
13
13
|
bindir: bin
|
14
14
|
cert_chain: []
|
15
|
-
date: 2022-
|
15
|
+
date: 2022-03-21 00:00:00.000000000 Z
|
16
16
|
dependencies:
|
17
17
|
- !ruby/object:Gem::Dependency
|
18
18
|
name: activemodel
|
@@ -23,7 +23,7 @@ dependencies:
|
|
23
23
|
version: '5.0'
|
24
24
|
- - "<="
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version:
|
26
|
+
version: 7.0.2
|
27
27
|
type: :runtime
|
28
28
|
prerelease: false
|
29
29
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -33,7 +33,7 @@ dependencies:
|
|
33
33
|
version: '5.0'
|
34
34
|
- - "<="
|
35
35
|
- !ruby/object:Gem::Version
|
36
|
-
version:
|
36
|
+
version: 7.0.2
|
37
37
|
- !ruby/object:Gem::Dependency
|
38
38
|
name: activerecord
|
39
39
|
requirement: !ruby/object:Gem::Requirement
|
@@ -43,7 +43,7 @@ dependencies:
|
|
43
43
|
version: '5.0'
|
44
44
|
- - "<="
|
45
45
|
- !ruby/object:Gem::Version
|
46
|
-
version:
|
46
|
+
version: 7.0.2
|
47
47
|
type: :runtime
|
48
48
|
prerelease: false
|
49
49
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -53,7 +53,7 @@ dependencies:
|
|
53
53
|
version: '5.0'
|
54
54
|
- - "<="
|
55
55
|
- !ruby/object:Gem::Version
|
56
|
-
version:
|
56
|
+
version: 7.0.2
|
57
57
|
- !ruby/object:Gem::Dependency
|
58
58
|
name: bcrypt
|
59
59
|
requirement: !ruby/object:Gem::Requirement
|
@@ -119,7 +119,7 @@ dependencies:
|
|
119
119
|
version: 2.6.5
|
120
120
|
- - "<"
|
121
121
|
- !ruby/object:Gem::Version
|
122
|
-
version: '3.
|
122
|
+
version: '3.2'
|
123
123
|
type: :runtime
|
124
124
|
prerelease: false
|
125
125
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -129,7 +129,7 @@ dependencies:
|
|
129
129
|
version: 2.6.5
|
130
130
|
- - "<"
|
131
131
|
- !ruby/object:Gem::Version
|
132
|
-
version: '3.
|
132
|
+
version: '3.2'
|
133
133
|
- !ruby/object:Gem::Dependency
|
134
134
|
name: pg
|
135
135
|
requirement: !ruby/object:Gem::Requirement
|
@@ -443,7 +443,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
443
443
|
- !ruby/object:Gem::Version
|
444
444
|
version: '0'
|
445
445
|
requirements: []
|
446
|
-
rubygems_version: 3.
|
446
|
+
rubygems_version: 3.3.7
|
447
447
|
signing_key:
|
448
448
|
specification_version: 4
|
449
449
|
summary: Event sourcing framework for Ruby
|