nexia_event_store 0.5.11 → 0.6.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 +4 -4
- data/lib/event_store/aggregate.rb +3 -3
- data/lib/event_store/client.rb +9 -9
- data/lib/event_store/event_stream.rb +16 -25
- data/lib/event_store/snapshot.rb +24 -24
- data/lib/event_store/version.rb +1 -1
- data/lib/event_store.rb +1 -1
- data/spec/event_store/client_spec.rb +33 -43
- data/spec/event_store/snapshot_spec.rb +3 -3
- data/spec/unit/snapshot_unit_spec.rb +17 -13
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: dc9b1f564f3ddc8e4d22914517f12d8cc6f53d02
|
4
|
+
data.tar.gz: e1c77390b4b25728ed97aff1704aa1ecbfabf7c8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 605f0b48862fd33d06ae738ed0be5c67c5a0bca60c0f02f4358f02017a81d98de7cc4400eec8e0acf03319d047012ae68e121b329b4c87b67450779631066d2f
|
7
|
+
data.tar.gz: d52f66b078358357c0f8b86a30d81e2659e24a9da5114d1155f2f4034609b9eba1173f54376db965fac5aba347adc2cd5c2b0fae052d861da78680e76128b46b
|
data/lib/event_store/client.rb
CHANGED
@@ -4,12 +4,12 @@ module EventStore
|
|
4
4
|
|
5
5
|
def_delegators :aggregate,
|
6
6
|
:delete_snapshot!,
|
7
|
-
:
|
8
|
-
:
|
7
|
+
:snapshot_event_id_table,
|
8
|
+
:event_id,
|
9
|
+
:event_id_for,
|
9
10
|
:event_table,
|
10
11
|
:type,
|
11
|
-
:id
|
12
|
-
:version
|
12
|
+
:id
|
13
13
|
|
14
14
|
def_delegators :event_stream,
|
15
15
|
:count
|
@@ -46,8 +46,8 @@ module EventStore
|
|
46
46
|
translate_events(raw_event_stream)
|
47
47
|
end
|
48
48
|
|
49
|
-
def event_stream_from(
|
50
|
-
translate_events(aggregate.events_from(
|
49
|
+
def event_stream_from(event_id, max=nil)
|
50
|
+
translate_events(aggregate.events_from(event_id, max))
|
51
51
|
end
|
52
52
|
|
53
53
|
def last_event_before(start_time, fully_qualified_names = [])
|
@@ -70,8 +70,8 @@ module EventStore
|
|
70
70
|
aggregate.event_stream
|
71
71
|
end
|
72
72
|
|
73
|
-
def raw_event_stream_from
|
74
|
-
aggregate.events_from(
|
73
|
+
def raw_event_stream_from(event_id, max=nil)
|
74
|
+
aggregate.events_from(event_id, max)
|
75
75
|
end
|
76
76
|
|
77
77
|
def destroy!
|
@@ -99,7 +99,7 @@ module EventStore
|
|
99
99
|
def translate_event(event_hash)
|
100
100
|
return if event_hash.empty?
|
101
101
|
occurred_at = TimeHacker.translate_occurred_at_from_local_to_gmt(event_hash[:occurred_at])
|
102
|
-
SerializedEvent.new event_hash[:fully_qualified_name], event_hash[:serialized_event], event_hash[:
|
102
|
+
SerializedEvent.new event_hash[:fully_qualified_name], event_hash[:serialized_event], event_hash[:id], occurred_at
|
103
103
|
end
|
104
104
|
end
|
105
105
|
end
|
@@ -11,28 +11,26 @@ module EventStore
|
|
11
11
|
end
|
12
12
|
|
13
13
|
def append(raw_events)
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
next_version += 1
|
20
|
-
ensure_all_attributes_have_values!(event)
|
21
|
-
event
|
22
|
-
end
|
23
|
-
|
24
|
-
events.multi_insert(prepared_events)
|
14
|
+
prepared_events = raw_events.map do |raw_event|
|
15
|
+
event = prepare_event(raw_event)
|
16
|
+
ensure_all_attributes_have_values!(event)
|
17
|
+
event
|
18
|
+
end
|
25
19
|
|
26
|
-
|
20
|
+
inserted_ids = events.multi_insert(prepared_events, return: :primary_key)
|
21
|
+
prepared_events.each_with_index do |event, idx|
|
22
|
+
event[:id] = inserted_ids[idx]
|
27
23
|
end
|
24
|
+
|
25
|
+
yield(prepared_events) if block_given?
|
28
26
|
end
|
29
27
|
|
30
28
|
def events
|
31
|
-
@events_query ||= EventStore.db.from(@event_table).where(:aggregate_id => @id.to_s).order(:
|
29
|
+
@events_query ||= EventStore.db.from(@event_table).where(:aggregate_id => @id.to_s).order(:id)
|
32
30
|
end
|
33
31
|
|
34
|
-
def events_from(
|
35
|
-
events.limit(max).where{
|
32
|
+
def events_from(event_id, max = nil)
|
33
|
+
events.limit(max).where{ id >= event_id.to_i }.all.map do |event|
|
36
34
|
event[:serialized_event] = EventStore.unescape_bytea(event[:serialized_event])
|
37
35
|
event
|
38
36
|
end
|
@@ -85,10 +83,9 @@ module EventStore
|
|
85
83
|
|
86
84
|
private
|
87
85
|
|
88
|
-
def prepare_event(raw_event
|
86
|
+
def prepare_event(raw_event)
|
89
87
|
raise ArgumentError.new("Cannot Append a Nil Event") unless raw_event
|
90
|
-
{ :
|
91
|
-
:aggregate_id => raw_event.aggregate_id,
|
88
|
+
{ :aggregate_id => raw_event.aggregate_id,
|
92
89
|
:occurred_at => Time.parse(raw_event.occurred_at.to_s).utc, #to_s truncates microseconds, which brake Time equality
|
93
90
|
:serialized_event => EventStore.escape_bytea(raw_event.serialized_event),
|
94
91
|
:fully_qualified_name => raw_event.fully_qualified_name,
|
@@ -97,17 +94,11 @@ module EventStore
|
|
97
94
|
end
|
98
95
|
|
99
96
|
def ensure_all_attributes_have_values!(event_hash)
|
100
|
-
[:aggregate_id, :fully_qualified_name, :occurred_at, :serialized_event
|
97
|
+
[:aggregate_id, :fully_qualified_name, :occurred_at, :serialized_event].each do |attribute_name|
|
101
98
|
if event_hash[attribute_name].to_s.strip.empty?
|
102
99
|
raise AttributeMissingError, "value required for #{attribute_name}"
|
103
100
|
end
|
104
101
|
end
|
105
102
|
end
|
106
|
-
|
107
|
-
def last_version
|
108
|
-
last = events.select(:version).last
|
109
|
-
last && last[:version] || -1
|
110
|
-
end
|
111
|
-
|
112
103
|
end
|
113
104
|
end
|
data/lib/event_store/snapshot.rb
CHANGED
@@ -4,13 +4,13 @@ module EventStore
|
|
4
4
|
class Snapshot
|
5
5
|
include Enumerable
|
6
6
|
|
7
|
-
attr_reader :
|
7
|
+
attr_reader :snapshot_event_id_table, :snapshot_table
|
8
8
|
|
9
9
|
def initialize aggregate
|
10
10
|
@aggregate = aggregate
|
11
11
|
@redis = EventStore.redis
|
12
12
|
@snapshot_table = "#{@aggregate.type}_snapshots_for_#{@aggregate.id}"
|
13
|
-
@
|
13
|
+
@snapshot_event_id_table = "#{@aggregate.type}_snapshot_event_ids_for_#{@aggregate.id}"
|
14
14
|
end
|
15
15
|
|
16
16
|
def exists?
|
@@ -21,12 +21,12 @@ module EventStore
|
|
21
21
|
to_a.last
|
22
22
|
end
|
23
23
|
|
24
|
-
def
|
25
|
-
(@redis.hget(
|
24
|
+
def event_id(snapshot_key =:current_event_id)
|
25
|
+
(@redis.hget(snapshot_event_id_table, snapshot_key) || -1).to_i
|
26
26
|
end
|
27
27
|
|
28
|
-
def
|
29
|
-
|
28
|
+
def event_id_for(fully_qualified_name, sub_key = nil)
|
29
|
+
event_id(snapshot_key(fully_qualified_name: fully_qualified_name, sub_key: sub_key))
|
30
30
|
end
|
31
31
|
|
32
32
|
def count(logger=default_logger)
|
@@ -43,13 +43,13 @@ module EventStore
|
|
43
43
|
result_hash = events_hash.inject([]) do |snapshot, (key, value)|
|
44
44
|
fully_qualified_name, _ = key.split(EventStore::SNAPSHOT_KEY_DELIMITER)
|
45
45
|
raw_event = value.split(EventStore::SNAPSHOT_DELIMITER)
|
46
|
-
|
46
|
+
event_id = raw_event.first.to_i
|
47
47
|
serialized_event = EventStore.unescape_bytea(raw_event[1])
|
48
48
|
occurred_at = Time.parse(raw_event.last)
|
49
|
-
snapshot + [SerializedEvent.new(fully_qualified_name, serialized_event,
|
49
|
+
snapshot + [SerializedEvent.new(fully_qualified_name, serialized_event, event_id, occurred_at)]
|
50
50
|
end
|
51
51
|
logger.debug { "#{self.class.name} serializing events took #{Time.now - t} seconds" }
|
52
|
-
result_hash.sort_by(&:
|
52
|
+
result_hash.sort_by(&:event_id).each { |e| yield e }
|
53
53
|
end
|
54
54
|
|
55
55
|
def rebuild_snapshot!(logger=default_logger)
|
@@ -69,25 +69,25 @@ module EventStore
|
|
69
69
|
end
|
70
70
|
|
71
71
|
def delete_snapshot!
|
72
|
-
EventStore.redis.del [snapshot_table,
|
72
|
+
EventStore.redis.del [snapshot_table, snapshot_event_id_table]
|
73
73
|
end
|
74
74
|
|
75
75
|
def store_snapshot(prepared_events)
|
76
76
|
valid_snapshot_events = []
|
77
|
-
|
77
|
+
valid_snapshot_event_ids = []
|
78
78
|
|
79
79
|
prepared_events.each do |event_hash|
|
80
|
-
if event_hash[:
|
81
|
-
valid_snapshot_events
|
82
|
-
|
80
|
+
if event_hash[:id].to_i > current_event_id_numbers[snapshot_key(event_hash)].to_i
|
81
|
+
valid_snapshot_events += snapshot_event(event_hash)
|
82
|
+
valid_snapshot_event_ids += snapshot_event_id(event_hash)
|
83
83
|
end
|
84
84
|
end
|
85
85
|
|
86
|
-
unless
|
87
|
-
|
86
|
+
unless valid_snapshot_event_ids.empty?
|
87
|
+
valid_snapshot_event_ids += [:current_event_id, valid_snapshot_event_ids.last.to_i]
|
88
88
|
|
89
89
|
@redis.multi do
|
90
|
-
@redis.hmset(
|
90
|
+
@redis.hmset(snapshot_event_id_table, valid_snapshot_event_ids)
|
91
91
|
@redis.hmset(snapshot_table, valid_snapshot_events)
|
92
92
|
end
|
93
93
|
end
|
@@ -106,24 +106,24 @@ module EventStore
|
|
106
106
|
def snapshot_event(event)
|
107
107
|
[
|
108
108
|
snapshot_key(event),
|
109
|
-
[ event[:
|
109
|
+
[ event[:id].to_s,
|
110
110
|
event[:serialized_event],
|
111
111
|
event[:occurred_at].to_s
|
112
112
|
].join(EventStore::SNAPSHOT_DELIMITER)
|
113
113
|
]
|
114
114
|
end
|
115
115
|
|
116
|
-
def
|
116
|
+
def snapshot_event_id(event)
|
117
117
|
[
|
118
118
|
snapshot_key(event),
|
119
|
-
event[:
|
119
|
+
event[:id]
|
120
120
|
]
|
121
121
|
end
|
122
122
|
|
123
|
-
def
|
124
|
-
|
125
|
-
|
126
|
-
|
123
|
+
def current_event_id_numbers
|
124
|
+
@redis.hgetall(snapshot_event_id_table).tap { |event_ids|
|
125
|
+
event_ids.default = -1
|
126
|
+
}
|
127
127
|
end
|
128
128
|
|
129
129
|
def read_raw_snapshot(logger=default_logger)
|
data/lib/event_store/version.rb
CHANGED
data/lib/event_store.rb
CHANGED
@@ -17,7 +17,7 @@ Sequel.extension :migration
|
|
17
17
|
|
18
18
|
module EventStore
|
19
19
|
Event = Struct.new(:aggregate_id, :occurred_at, :fully_qualified_name, :sub_key, :serialized_event)
|
20
|
-
SerializedEvent = Struct.new(:fully_qualified_name, :serialized_event, :
|
20
|
+
SerializedEvent = Struct.new(:fully_qualified_name, :serialized_event, :event_id, :occurred_at)
|
21
21
|
SNAPSHOT_DELIMITER = "__NexEvStDelim__"
|
22
22
|
SNAPSHOT_KEY_DELIMITER = ":"
|
23
23
|
NO_SUB_KEY = "NO_SUB_KEY"
|
@@ -15,7 +15,7 @@ describe EventStore::Client do
|
|
15
15
|
|
16
16
|
events_by_aggregate_id = {AGGREGATE_ID_ONE => [], AGGREGATE_ID_TWO => []}
|
17
17
|
@event_time = Time.parse("2001-01-01 00:00:00 UTC")
|
18
|
-
([AGGREGATE_ID_ONE]*5 + [AGGREGATE_ID_TWO]*5).shuffle.each_with_index do |aggregate_id,
|
18
|
+
([AGGREGATE_ID_ONE]*5 + [AGGREGATE_ID_TWO]*5).shuffle.each_with_index do |aggregate_id, event_id|
|
19
19
|
events_by_aggregate_id[aggregate_id.to_s] << EventStore::Event.new(aggregate_id.to_s, @event_time, "zone_1_event", "1", serialized_binary_event_data)
|
20
20
|
events_by_aggregate_id[aggregate_id.to_s] << EventStore::Event.new(aggregate_id.to_s, @event_time, "zone_2_event", "2", serialized_binary_event_data)
|
21
21
|
events_by_aggregate_id[aggregate_id.to_s] << EventStore::Event.new(aggregate_id.to_s, @event_time, "system_event", EventStore::NO_SUB_KEY, serialized_binary_event_data)
|
@@ -116,48 +116,49 @@ describe EventStore::Client do
|
|
116
116
|
end
|
117
117
|
|
118
118
|
|
119
|
-
describe '#
|
119
|
+
describe '#raw_event_streams_from_event_id' do
|
120
120
|
subject { es_client.new(AGGREGATE_ID_ONE, :device) }
|
121
|
+
let(:raw_stream) { subject.raw_event_stream }
|
122
|
+
let(:minimum_event_id) { raw_stream.events.all[1][:id] }
|
123
|
+
let(:events_from) { subject.raw_event_stream_from(minimum_event_id) }
|
121
124
|
|
122
|
-
it 'should return all the raw events in the stream starting from a certain
|
123
|
-
|
124
|
-
|
125
|
-
event_versions = raw_stream.inject([]){|m, event| m << event[:version]; m}
|
126
|
-
expect(event_versions.min).to be >= minimum_event_version
|
125
|
+
it 'should return all the raw events in the stream starting from a certain event_id' do
|
126
|
+
event_ids = events_from.inject([]){|m, event| m << event[:id]; m}
|
127
|
+
expect(event_ids.min).to be >= minimum_event_id
|
127
128
|
end
|
128
129
|
|
129
130
|
it 'should return no more than the maximum number of events specified above the ' do
|
130
|
-
max_number_of_events
|
131
|
-
|
132
|
-
raw_stream = subject.raw_event_stream_from(
|
131
|
+
max_number_of_events = 5
|
132
|
+
minimum_event_id = 2
|
133
|
+
raw_stream = subject.raw_event_stream_from(minimum_event_id, max_number_of_events)
|
133
134
|
expect(raw_stream.count).to eq(max_number_of_events)
|
134
135
|
end
|
135
136
|
|
136
137
|
it 'should be empty for version above the current highest version number' do
|
137
|
-
raw_stream = subject.raw_event_stream_from(subject.
|
138
|
+
raw_stream = subject.raw_event_stream_from(subject.event_id + 1)
|
138
139
|
expect(raw_stream).to be_empty
|
139
140
|
end
|
140
141
|
end
|
141
142
|
|
142
|
-
describe '
|
143
|
+
describe 'event_stream_from_event_id' do
|
143
144
|
subject { es_client.new(AGGREGATE_ID_ONE, :device) }
|
144
145
|
|
145
|
-
it 'should return all the raw events in the stream starting from a certain
|
146
|
-
|
147
|
-
raw_stream = subject.raw_event_stream_from(
|
148
|
-
|
149
|
-
expect(
|
146
|
+
it 'should return all the raw events in the stream starting from a certain event_id' do
|
147
|
+
minimum_event_id = 2
|
148
|
+
raw_stream = subject.raw_event_stream_from(minimum_event_id)
|
149
|
+
event_ids = raw_stream.inject([]){|m, event| m << event[:id]; m}
|
150
|
+
expect(event_ids.min).to be >= minimum_event_id
|
150
151
|
end
|
151
152
|
|
152
153
|
it 'should return no more than the maximum number of events specified above the ' do
|
153
154
|
max_number_of_events = 5
|
154
|
-
|
155
|
-
raw_stream = subject.raw_event_stream_from(
|
155
|
+
minimum_event_id = 2
|
156
|
+
raw_stream = subject.raw_event_stream_from(minimum_event_id, max_number_of_events)
|
156
157
|
expect(raw_stream.count).to eq(max_number_of_events)
|
157
158
|
end
|
158
159
|
|
159
|
-
it 'should be empty for
|
160
|
-
raw_stream = subject.raw_event_stream_from(subject.
|
160
|
+
it 'should be empty for event_id above the current highest event id' do
|
161
|
+
raw_stream = subject.raw_event_stream_from(subject.event_id + 1)
|
161
162
|
expect(raw_stream).to eq([])
|
162
163
|
end
|
163
164
|
end
|
@@ -242,10 +243,10 @@ describe EventStore::Client do
|
|
242
243
|
let(:client) { es_client.new(AGGREGATE_ID_ONE, :device) }
|
243
244
|
|
244
245
|
it 'should return the last event in the event stream' do
|
245
|
-
last_event = EventStore.db.from(client.event_table).where(aggregate_id: AGGREGATE_ID_ONE).order(:
|
246
|
+
last_event = EventStore.db.from(client.event_table).where(aggregate_id: AGGREGATE_ID_ONE).order(:id).last
|
246
247
|
peek = client.peek
|
247
248
|
expect(peek.fully_qualified_name).to eq(last_event[:fully_qualified_name])
|
248
|
-
expect(peek.
|
249
|
+
expect(peek.event_id).to eq(last_event[:id])
|
249
250
|
end
|
250
251
|
end
|
251
252
|
end
|
@@ -260,7 +261,7 @@ describe EventStore::Client do
|
|
260
261
|
let(:really_new_event) { EventStore::Event.new(AGGREGATE_ID_ONE, (event_time + 100).utc, "really_new", "zone", "#{1002.to_s(2)}_foo") }
|
261
262
|
let(:duplicate_event) { EventStore::Event.new(AGGREGATE_ID_ONE, (event_time).utc, "duplicate", "zone", "#{12.to_s(2)}_foo") }
|
262
263
|
|
263
|
-
describe "when expected
|
264
|
+
describe "when expected event id is greater than the last event id" do
|
264
265
|
describe 'and there are no prior events of type' do
|
265
266
|
before(:each) do
|
266
267
|
client.append([old_event])
|
@@ -280,16 +281,16 @@ describe EventStore::Client do
|
|
280
281
|
expect(client.count).to eq(initial_count + events.length)
|
281
282
|
end
|
282
283
|
|
283
|
-
it "should
|
284
|
+
it "should change the event id number" do
|
284
285
|
events = [new_event, really_new_event]
|
285
|
-
expect{client.append(events)}.to change(client, :
|
286
|
+
expect{ client.append(events) }.to change(client, :event_id)
|
286
287
|
end
|
287
288
|
|
288
|
-
it "sets the snapshot
|
289
|
-
expect(client.snapshot.
|
289
|
+
it "sets the snapshot event id number to match that of the last event in the aggregate's event stream" do
|
290
|
+
expect(client.snapshot.event_id).to eq(client.raw_event_stream.last[:id])
|
290
291
|
|
291
292
|
client.append([new_event, really_new_event])
|
292
|
-
expect(client.snapshot.
|
293
|
+
expect(client.snapshot.event_id).to eq(client.raw_event_stream.last[:id])
|
293
294
|
end
|
294
295
|
|
295
296
|
it "should write-through-cache the event in a snapshot without duplicating events" do
|
@@ -311,12 +312,6 @@ describe EventStore::Client do
|
|
311
312
|
client.append([old_event])
|
312
313
|
end
|
313
314
|
|
314
|
-
xit 'should raise a ConcurrencyError if the the event version is less than current version' do
|
315
|
-
client.append([duplicate_event])
|
316
|
-
reset_current_version_for(client)
|
317
|
-
expect { client.append([duplicate_event]) }.to raise_error(EventStore::ConcurrencyError)
|
318
|
-
end
|
319
|
-
|
320
315
|
it 'should not raise an error when two events of the same type are appended' do
|
321
316
|
client.append([duplicate_event])
|
322
317
|
client.append([duplicate_event]) #will fail automatically if it throws an error, no need for assertions (which now print warning for some reason)
|
@@ -331,11 +326,11 @@ describe EventStore::Client do
|
|
331
326
|
expect(client.snapshot.to_a).to eq(expected)
|
332
327
|
end
|
333
328
|
|
334
|
-
it "sets the snapshot
|
335
|
-
expect(client.snapshot.
|
329
|
+
it "sets the snapshot event id to match that of the last event in the aggregate's event stream" do
|
330
|
+
expect(client.snapshot.event_id).to eq(client.raw_event_stream.last[:id])
|
336
331
|
|
337
332
|
client.append([old_event, old_event])
|
338
|
-
expect(client.snapshot.
|
333
|
+
expect(client.snapshot.event_id).to eq(client.raw_event_stream.last[:id])
|
339
334
|
end
|
340
335
|
end
|
341
336
|
end
|
@@ -370,11 +365,6 @@ describe EventStore::Client do
|
|
370
365
|
end
|
371
366
|
end
|
372
367
|
end
|
373
|
-
|
374
|
-
def reset_current_version_for(client)
|
375
|
-
aggregate = client.instance_variable_get("@aggregate")
|
376
|
-
EventStore.redis.hset(aggregate.snapshot_version_table, :current_version, 1000)
|
377
|
-
end
|
378
368
|
end
|
379
369
|
|
380
370
|
describe '#last_event_before' do
|
@@ -11,8 +11,8 @@ module EventStore
|
|
11
11
|
|
12
12
|
it "should build an empty snapshot for a new client" do
|
13
13
|
expect(client.snapshot.any?).to eq(false)
|
14
|
-
expect(client.
|
15
|
-
expect(EventStore.redis.hget(client.
|
14
|
+
expect(client.event_id).to eq(-1)
|
15
|
+
expect(EventStore.redis.hget(client.snapshot_event_id_table, :current_event_id)).to eq(nil)
|
16
16
|
end
|
17
17
|
|
18
18
|
it "a client should rebuild a snapshot" do
|
@@ -61,7 +61,7 @@ module EventStore
|
|
61
61
|
end
|
62
62
|
|
63
63
|
it "increments the version number of the snapshot when an event is appended" do
|
64
|
-
expect(client.snapshot.
|
64
|
+
expect(client.snapshot.event_id).to eq(client.raw_event_stream.last[:id])
|
65
65
|
end
|
66
66
|
end
|
67
67
|
|
@@ -11,13 +11,13 @@ module EventStore
|
|
11
11
|
|
12
12
|
subject(:snapshot) { EventStore::Snapshot.new(aggregate) }
|
13
13
|
|
14
|
-
it "has a
|
15
|
-
expect(snapshot.
|
14
|
+
it "has a event_id table for the snapshot" do
|
15
|
+
expect(snapshot.snapshot_event_id_table).to eq "#{aggregate_type}_snapshot_event_ids_for_#{aggregate_id}"
|
16
16
|
end
|
17
17
|
|
18
18
|
context "with events in the snapshot table" do
|
19
19
|
let(:first_event) {
|
20
|
-
{
|
20
|
+
{ id: 1,
|
21
21
|
fully_qualified_name: "fqn",
|
22
22
|
sub_key: "sub",
|
23
23
|
serialized_event: EventStore.escape_bytea("cheerios"),
|
@@ -25,7 +25,7 @@ module EventStore
|
|
25
25
|
}
|
26
26
|
}
|
27
27
|
let(:last_event) {
|
28
|
-
{
|
28
|
+
{ id: 2,
|
29
29
|
fully_qualified_name: "fqn2",
|
30
30
|
sub_key: "sub2",
|
31
31
|
serialized_event: EventStore.escape_bytea("cheerios2"),
|
@@ -39,29 +39,29 @@ module EventStore
|
|
39
39
|
describe "#last_event" do
|
40
40
|
let(:events) { [ last_event, first_event ] }
|
41
41
|
|
42
|
-
it "returns the event with the highest
|
42
|
+
it "returns the event with the highest event_id" do
|
43
43
|
expect(snapshot.last_event.fully_qualified_name).to eq(last_event[:fully_qualified_name])
|
44
44
|
end
|
45
45
|
end
|
46
46
|
|
47
|
-
describe "#
|
48
|
-
it "is the highest
|
49
|
-
expect(snapshot.
|
47
|
+
describe "#event_id" do
|
48
|
+
it "is the highest event_id of the last inserted event in the snapshot" do
|
49
|
+
expect(snapshot.event_id).to eq(last_event[:id])
|
50
50
|
end
|
51
51
|
end
|
52
52
|
|
53
|
-
describe "#
|
53
|
+
describe "#event_id_for" do
|
54
54
|
let(:subkey) { first_event[:sub_key] }
|
55
55
|
let(:fqn) { first_event[:fully_qualified_name] }
|
56
56
|
|
57
|
-
it "returns the
|
58
|
-
expect(snapshot.
|
57
|
+
it "returns the event_id number for the last event of specific fqn" do
|
58
|
+
expect(snapshot.event_id_for(fqn, subkey)).to eq(first_event[:id])
|
59
59
|
end
|
60
60
|
end
|
61
61
|
|
62
62
|
describe "#rebuild_snapshot!" do
|
63
63
|
it "deletes the existing snapshot" do
|
64
|
-
expect(redis).to receive(:del).with([snapshot.snapshot_table , snapshot.
|
64
|
+
expect(redis).to receive(:del).with([snapshot.snapshot_table , snapshot.snapshot_event_id_table])
|
65
65
|
snapshot.rebuild_snapshot!
|
66
66
|
end
|
67
67
|
|
@@ -78,7 +78,6 @@ module EventStore
|
|
78
78
|
describe "events" do
|
79
79
|
let(:serialized_attrs) { [ :fully_qualified_name,
|
80
80
|
:serialized_event,
|
81
|
-
:version,
|
82
81
|
:occurred_at ] }
|
83
82
|
|
84
83
|
it "contains SerializedEvents" do
|
@@ -92,6 +91,11 @@ module EventStore
|
|
92
91
|
}
|
93
92
|
end
|
94
93
|
|
94
|
+
it "maps the event_id to the serialized event's id" do
|
95
|
+
expect(snapshot.to_a.first.event_id).to eq(first_event[:id])
|
96
|
+
expect(snapshot.to_a.last.event_id).to eq(last_event[:id])
|
97
|
+
end
|
98
|
+
|
95
99
|
it "unescapes the serialized events" do
|
96
100
|
expected_event = EventStore.unescape_bytea(first_event[:serialized_event])
|
97
101
|
expect(snapshot.first.serialized_event).to eq(expected_event)
|