nexia_event_store 0.9.1 → 0.10.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: 17ccc001ca06cb2c0fdc059a29a30f63e00f028b
4
- data.tar.gz: 8b3538b01bb2cb879905c4edd13dc92f708c4d8e
3
+ metadata.gz: f2dba3805be9987a863b9c80cad063ff5ce6ecd2
4
+ data.tar.gz: 735780ad87bad4795370e51bcf22b71f85184e51
5
5
  SHA512:
6
- metadata.gz: 837398a20abc3b289698d61711da897da5824ceb384a4fdcd21b5143ad11f8a71552567c81d1202c643e1bf95a9178119027602d7a18a744e2352ed63c5023ec
7
- data.tar.gz: 58671b2fe871f9664ddd1153528c27c55063b4665d8fccae638f62a191e8c6e86b31ed98047e1b2728013958e4e56acc1eb8ad19815eda2aa2d4edbff1875aea
6
+ metadata.gz: 2b3aac7d78671e3b9ffd7c136d88ebded20358121fdf9759762cdd846e697325972725e1183a570412e475fe7fbed5bc3fd9768e885037efb1cf848e122f9ad5
7
+ data.tar.gz: 4da1989af164abf4802e5e963491fd68a2da8993154f568107ed8e02d0e8f1e88b4a576371032ee787c16906151a89fa0fabef2e3d94286c69c9d21343d79ddd
@@ -41,12 +41,7 @@ module EventStore
41
41
 
42
42
  t = Time.now
43
43
  result_hash = events_hash.inject([]) do |snapshot, (key, value)|
44
- fully_qualified_name, _ = key.split(EventStore::SNAPSHOT_KEY_DELIMITER)
45
- raw_event = value.split(EventStore::SNAPSHOT_DELIMITER)
46
- event_id = raw_event.first.to_i
47
- serialized_event = EventStore.unescape_bytea(raw_event[1])
48
- occurred_at = Time.parse(raw_event.last)
49
- snapshot + [SerializedEvent.new(fully_qualified_name, serialized_event, event_id, occurred_at)]
44
+ snapshot + [serialized_event_from_snapshot_event(key, value)]
50
45
  end
51
46
  logger.debug { "#{self.class.name} serializing events took #{Time.now - t} seconds" }
52
47
  result_hash.sort_by(&:event_id).each { |e| yield e }
@@ -99,16 +94,47 @@ module EventStore
99
94
  end
100
95
 
101
96
  def update_fqns!(logger = default_logger)
102
- updated_events = replace_fqns_in_snapshot_hash(read_with_rebuild(logger)) { |fqn| yield fqn }
97
+ logger.debug { "Replacing FQNs in snapshot events" }
98
+ updated_events = replace_fqns_in_snapshot_hash(read_with_rebuild(logger)) { |fqn| yield fqn }
99
+
100
+ logger.debug { "Replacing FQNs in snapshot event ids" }
103
101
  updated_event_ids = replace_fqns_in_snapshot_hash(current_event_id_numbers) { |fqn|
104
102
  fqn == 'current_event_id' ? fqn : (yield fqn)
105
103
  }
106
104
 
107
- update_snapshot_tables(updated_event_ids, updated_events, replace: true)
105
+ logger.debug "Updating snapshot tables in redis"
106
+ replace_snapshot_tables(updated_event_ids, updated_events)
107
+ end
108
+
109
+ def reject!(logger = default_logger)
110
+ events_to_keep = read_with_rebuild(logger)
111
+ event_ids = current_event_id_numbers
112
+
113
+ events_to_keep.dup.each { |snapshot_key, snapshot_event|
114
+ serialized_event = serialized_event_from_snapshot_event(snapshot_key, snapshot_event)
115
+ drop_it = yield serialized_event
116
+
117
+ if drop_it
118
+ events_to_keep.delete(snapshot_key)
119
+ event_ids.delete(snapshot_key)
120
+ end
121
+ }
122
+
123
+ replace_snapshot_tables(event_ids.flatten, events_to_keep.flatten)
108
124
  end
109
125
 
110
126
  private
111
127
 
128
+ def serialized_event_from_snapshot_event(snapshot_key, snapshot_value)
129
+ fully_qualified_name, _ = snapshot_key.split(EventStore::SNAPSHOT_KEY_DELIMITER)
130
+ raw_event = snapshot_value.split(EventStore::SNAPSHOT_DELIMITER)
131
+ event_id = raw_event.first.to_i
132
+ serialized_event = EventStore.unescape_bytea(raw_event[1])
133
+ occurred_at = Time.parse(raw_event.last)
134
+
135
+ SerializedEvent.new(fully_qualified_name, serialized_event, event_id, occurred_at)
136
+ end
137
+
112
138
  def replace_fqns_in_snapshot_hash(snapshot_keyed_hash)
113
139
  snapshot_keyed_hash.inject([]) { |memo, (snapshot_key, value)|
114
140
  new_key = replace_fqn_in_snapshot_key(snapshot_key) { |fqn| yield fqn }
@@ -122,16 +148,21 @@ module EventStore
122
148
  [new_fqn, sub_key].compact.join(EventStore::SNAPSHOT_KEY_DELIMITER)
123
149
  end
124
150
 
125
- # params are flattened hashes, i.e., [key1, val1, key2, val2, ...]
126
- def update_snapshot_tables(event_ids_array, events_array, replace: false)
151
+ def replace_snapshot_tables(event_ids_array, events_array)
127
152
  @redis.multi do
128
- @redis.del snapshot_event_id_table if replace
129
- @redis.hmset(snapshot_event_id_table, event_ids_array)
130
- @redis.del snapshot_table if replace
131
- @redis.hmset(snapshot_table, events_array)
153
+ delete_snapshot!
154
+ update_snapshot_tables(event_ids_array, events_array)
132
155
  end
133
156
  end
134
157
 
158
+ # params are flattened hashes, i.e., [key1, val1, key2, val2, ...]
159
+ def update_snapshot_tables(event_ids_array, events_array)
160
+ return unless events_array.any?
161
+
162
+ @redis.hmset(snapshot_event_id_table, event_ids_array)
163
+ @redis.hmset(snapshot_table, events_array)
164
+ end
165
+
135
166
  def default_logger
136
167
  Logger.new('/dev/null')
137
168
  end
@@ -1,3 +1,3 @@
1
1
  module EventStore
2
- VERSION = '0.9.1'
2
+ VERSION = '0.10.0'
3
3
  end
@@ -23,66 +23,110 @@ module EventStore
23
23
  end
24
24
 
25
25
  context "with events in the stream" do
26
- let(:client) { EventStore::Client.new(AGGREGATE_ID_TWO) }
26
+ let(:client) { EventStore::Client.new(AGGREGATE_ID_TWO) }
27
+ let(:snapshot) { client.snapshot }
28
+ let(:events) { events_for(AGGREGATE_ID_TWO) }
27
29
 
28
- before do
29
- expect(client.snapshot.count).to eq(0)
30
- client.append events_for(AGGREGATE_ID_TWO)
31
- end
30
+ before {
31
+ expect(snapshot.count).to eq(0)
32
+ client.append events
33
+ }
32
34
 
33
35
  describe "#count" do
34
36
  it "delegates to the snapshot hash" do
35
- expect(client.snapshot.count).to eq(8)
37
+ expect(snapshot.count).to eq(8)
36
38
  end
37
39
  end
38
40
 
39
41
  describe "#update_fqns!" do
40
- let(:original_events) { client.snapshot.to_a }
42
+ let(:original_events) { snapshot.to_a }
41
43
 
42
44
  it "replaces fully qualified names in the snapshot with the value of a block" do
43
- client.snapshot.update_fqns! { |fqn|
45
+ snapshot.update_fqns! { |fqn|
44
46
  fqn =~ /^(e[0-9])/ ? fqn.upcase : fqn
45
47
  }
46
48
 
47
49
  expected_snapshot_events = original_events.map { |serialized_event| serialized_event.fully_qualified_name.upcase }
48
- expect(client.snapshot.map(&:fully_qualified_name).to_set).to eq(expected_snapshot_events.to_set)
50
+ expect(snapshot.map(&:fully_qualified_name).to_set).to eq(expected_snapshot_events.to_set)
49
51
  end
50
52
 
51
53
  it "does not affect the current event id" do
52
- old_event_id = client.snapshot.event_id
54
+ old_event_id = snapshot.event_id
53
55
 
54
- client.snapshot.update_fqns! { |fqn| fqn.upcase }
56
+ snapshot.update_fqns! { |fqn| fqn.upcase }
55
57
 
56
- new_event_id = client.snapshot.event_id
58
+ new_event_id = snapshot.event_id
57
59
 
58
60
  expect(new_event_id).to eq(old_event_id)
59
61
  end
60
62
 
61
63
  it "doesn't affect the fully qualified name when the block returns nil" do
62
64
  old_fqns = original_events.map(&:fully_qualified_name)
63
- client.snapshot.update_fqns! { |_fqn| nil }
65
+ snapshot.update_fqns! { |_fqn| nil }
66
+
67
+ expect(snapshot.map(&:fully_qualified_name).to_set).to eq(old_fqns.to_set)
68
+ end
69
+ end
70
+
71
+ describe "#reject!" do
72
+ it "yields the serialized event to the block" do
73
+ snapshot.reject! { |serialized_event|
74
+ expect(events.map(&:fully_qualified_name)).to include(serialized_event.fully_qualified_name)
75
+ expect(events.map(&:serialized_event)).to include(serialized_event.serialized_event)
76
+ }
77
+ end
78
+
79
+ context "when the block returns true" do
80
+ before(:each) { snapshot.reject! { |serialized_event| serialized_event.fully_qualified_name == 'e1' } }
81
+
82
+ it "removes the event from the snapshot" do
83
+ expect(snapshot.map(&:fully_qualified_name)).not_to include('e1')
84
+ end
85
+
86
+ it "removes the event id from the snapshot" do
87
+ expect(snapshot.event_id_for('e1')).to eq(-1)
88
+ end
89
+ end
90
+
91
+ context "when the block returns false" do
92
+ before(:each) { snapshot.reject! { |serialized_event| serialized_event.fully_qualified_name != 'e1' } }
93
+
94
+ it "retains the event in the snapshot" do
95
+ expect(snapshot.map(&:fully_qualified_name)).to include('e1')
96
+ end
97
+
98
+ it "retains the event id in the snapshot" do
99
+ expect(snapshot.event_id_for('e1')).not_to eq(-1)
100
+ end
101
+ end
102
+
103
+ context "when all events are rejected" do
104
+ before(:each) { snapshot.reject! { true } }
64
105
 
65
- expect(client.snapshot.map(&:fully_qualified_name).to_set).to eq(old_fqns.to_set)
106
+ it "deletes the snapshot out of Redis" do
107
+ expect(EventStore.redis.keys(snapshot.snapshot_table).length).to eq(0)
108
+ expect(EventStore.redis.keys(snapshot.snapshot_event_id_table).length).to eq(0)
109
+ end
66
110
  end
67
111
  end
68
112
 
69
113
  it "rebuilds a snapshot after it is deleted" do
70
- snapshot = client.snapshot
114
+ snapshot = snapshot
71
115
  client.delete_snapshot!
72
116
  client.rebuild_snapshot!
73
- expect(client.snapshot).to eq(snapshot)
117
+ expect(snapshot).to eq(snapshot)
74
118
  end
75
119
 
76
120
  it "automatically rebuilds the snapshot if events exist, but the snapshot is empty" do
77
- snapshot = client.snapshot
121
+ snapshot = snapshot
78
122
  client.delete_snapshot!
79
- expect(client.snapshot).to eq(snapshot)
123
+ expect(snapshot).to eq(snapshot)
80
124
  end
81
125
 
82
126
  it "finds the most recent records for each type" do
83
127
  expected_snapshot_events = %w{e3 e1 e2 e5 e4 e7 e8 e7} #sorted by version no
84
128
  expected_snapshot = serialized_events(expected_snapshot_events)
85
- actual_snapshot = client.snapshot
129
+ actual_snapshot = snapshot
86
130
 
87
131
  expect(client.event_stream.count).to eq(15)
88
132
  expect(actual_snapshot.map(&:fully_qualified_name)).to eq(expected_snapshot_events)
@@ -91,7 +135,7 @@ module EventStore
91
135
  end
92
136
 
93
137
  it "increments the version number of the snapshot when an event is appended" do
94
- expect(client.snapshot.event_id).to eq(client.raw_event_stream.last[:id])
138
+ expect(snapshot.event_id).to eq(client.raw_event_stream.last[:id])
95
139
  end
96
140
  end
97
141
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: nexia_event_store
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.1
4
+ version: 0.10.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Paul Saieg, John Colvin
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2016-03-16 00:00:00.000000000 Z
12
+ date: 2016-03-17 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: bundler