sandthorn 0.10.3 → 0.11.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: 567a5ca0b81764696a4a80323cabeca004109fc6
4
- data.tar.gz: 90db28c455cc71ae90df453771b48b15d53a453e
3
+ metadata.gz: 3a2f65aa6777c6570a39697fe0dd6edcbc5fe17d
4
+ data.tar.gz: 0a72c05d0fef7caf7c752bb24472a643b51b2854
5
5
  SHA512:
6
- metadata.gz: 3499edfb4c94c63c5d2a82954e125e274109697ad0101a33c484959971f6b8d07e0c57b6573197e7758328f45460cf34debaf7e0bb9244bab05329ddb14b55ac
7
- data.tar.gz: 83bb3743729b952d596f4b6583343fb055933ef480f137e60734753aceee7cf9acc9ce8a5e06e72a3e0894d0c665b5b3eb58c2f4a73288e7d4fe7b9f66311053
6
+ metadata.gz: a3afc677df878cb3ae51f27e3b2beb37e82d549992a0915ffcedeccdcfcbe058780b525d4c593d508495063fa2e093e74d0252846bc3bcd7fd6ccb3e3236ea66
7
+ data.tar.gz: 3b6a3637a931aedab5c8b1a18f76100b945ee9e84fe8dc83a0f44322e8c91cb927b40d3335720a6b08fefab0465918c4be09304915fe641cef3843b2e64f37b5
data/Gemfile CHANGED
@@ -1,4 +1,4 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
3
  # Specify your gem's dependencies in sandthorn.gemspec
4
- gemspec
4
+ gemspec
data/README.md CHANGED
@@ -182,20 +182,21 @@ Sandthorn.configure do |conf|
182
182
  end
183
183
  ```
184
184
 
185
- ## Data serialization / deserialization
185
+ ## Data serialization
186
186
 
187
- Its possible to configure how events and snapshots are serialized / deserialized. The default are YAML but can be overloaded in the configure block.
187
+ Its possible to configure how events and snapshots are serialized. Since version `0.11.0` of Sandthorn the serialization of events and snapshots is the responsibility of the driver. This means drivers can have different serialization mechanism, independent of each other.
188
+
189
+ The default serializer of the Sequel driver is YAML.
190
+
191
+ Here's how to use the Oj gem to serialize data in the Sequel driver:
188
192
 
189
193
  ```ruby
190
- Sandthorn.configure do |conf|
191
- conf.serializer = Proc.new { |data| Oj::dump(data) }
192
- conf.deserializer = Proc.new { |data| Oj::load(data) }
193
- conf.snapshot_serializer = Proc.new { |data| Oj::dump(data) }
194
- conf.snapshot_deserializer = Proc.new { |data| Oj::load(data) }
195
- end
194
+ oj_driver = SandthornDriverSequel.driver_from_connection(connection: Sequel.sqlite) { |conf|
195
+ conf.event_serializer = Proc.new { |data| Oj::dump(data) }
196
+ conf.event_deserializer = Proc.new { |data| Oj::load(data) }
197
+ }
196
198
  ```
197
199
 
198
-
199
200
  # Usage
200
201
 
201
202
  ## Aggregate Root
@@ -238,7 +239,7 @@ end
238
239
 
239
240
  Its possible to add a default_attributes method on an aggregate and set default values to new and already created aggregates.
240
241
 
241
- The default_attributes method will be run before initialize on Class.new and before the events when an aggregate is rebuilt. This will make is possible to add default attributes to an aggregate during its hole life cycle.
242
+ The `default_attributes` method will be run before initialize on Class.new and before the events when an aggregate is rebuilt. This will make is possible to add default attributes to an aggregate during its hole life cycle.
242
243
 
243
244
  ```ruby
244
245
  def default_attributes
data/lib/sandthorn.rb CHANGED
@@ -10,7 +10,7 @@ module Sandthorn
10
10
  class << self
11
11
  extend Forwardable
12
12
 
13
- def_delegators :configuration, :event_stores, :serialize, :deserialize, :serialize_snapshot, :deserialize_snapshot
13
+ def_delegators :configuration, :event_stores
14
14
 
15
15
  def default_event_store
16
16
  event_stores.default_store
@@ -28,8 +28,6 @@ module Sandthorn
28
28
  @configuration ||= Configuration.new
29
29
  end
30
30
 
31
-
32
-
33
31
  def generate_aggregate_id
34
32
  SecureRandom.uuid
35
33
  end
@@ -46,12 +44,8 @@ module Sandthorn
46
44
  event_store_for(aggregate_type).get_aggregate_events_from_snapshot aggregate_id
47
45
  end
48
46
 
49
- def save_snapshot(
50
- aggregate_type: missing_key(:aggregate_type),
51
- aggregate_snapshot: missing_key(:aggregate_snapshot),
52
- aggregate_id: missing_key(:aggregate_id)
53
- )
54
- event_store_for(aggregate_type).save_snapshot(aggregate_snapshot, aggregate_id)
47
+ def save_snapshot(aggregate)
48
+ event_store_for(aggregate.class).save_snapshot(aggregate)
55
49
  end
56
50
 
57
51
  def get_aggregate_list_by_type aggregate_type
@@ -62,8 +56,6 @@ module Sandthorn
62
56
  event_store = find_event_store(event_store)
63
57
  events = event_store.get_events aggregate_types: aggregate_types, take: take, after_sequence_number: after_sequence_number
64
58
  events.map do |event|
65
- event[:event_args] = deserialize event[:event_data]
66
- event.delete(:event_data)
67
59
  Event.new(event)
68
60
  end
69
61
  end
@@ -111,67 +103,10 @@ module Sandthorn
111
103
  @event_stores = EventStores.new(store)
112
104
  end
113
105
 
114
- def serializer=(block)
115
- @serializer = block if block.is_a? Proc
116
- end
117
-
118
- def deserializer=(block)
119
- @deserializer = block if block.is_a? Proc
120
- end
121
-
122
- def serializer
123
- @serializer || default_serializer
124
- end
125
-
126
- def deserializer
127
- @deserializer || default_deserializer
128
- end
129
-
130
- def default_serializer
131
- -> (data) { YAML.dump(data) }
132
- end
133
-
134
- def default_deserializer
135
- -> (data) { YAML.load(data) }
136
- end
137
-
138
- def serialize(data)
139
- serializer.call(data)
140
- end
141
-
142
- def deserialize(data)
143
- deserializer.call(data)
144
- end
145
-
146
- def snapshot_serializer=(block)
147
- @snapshot_serializer = block if block.is_a? Proc
148
- end
149
-
150
- def snapshot_deserializer=(block)
151
- @snapshot_deserializer = block if block.is_a? Proc
152
- end
153
-
154
- def snapshot_serializer
155
- @snapshot_serializer || default_serializer
156
- end
157
-
158
- def snapshot_deserializer
159
- @snapshot_deserializer || default_deserializer
160
- end
161
-
162
- def serialize_snapshot(data)
163
- snapshot_serializer.call(data)
164
- end
165
-
166
- def deserialize_snapshot data
167
- snapshot_deserializer.call(data)
168
- end
169
-
170
106
  def map_types= data
171
107
  @event_stores.map_types data
172
108
  end
173
109
 
174
-
175
110
  alias_method :event_stores=, :event_store=
176
111
  end
177
112
  end
@@ -10,6 +10,7 @@ module Sandthorn
10
10
  attr_reader :aggregate_trace_information
11
11
 
12
12
  alias :id :aggregate_id
13
+ alias :aggregate_version :aggregate_current_event_version
13
14
 
14
15
 
15
16
  def aggregate_base_initialize
@@ -19,12 +20,7 @@ module Sandthorn
19
20
  end
20
21
 
21
22
  def save
22
- aggregate_events.each do |event|
23
- event[:event_data] = Sandthorn.serialize event[:event_args]
24
- event[:event_args] = nil #Not send extra data over the wire
25
- end
26
-
27
- unless aggregate_events.empty?
23
+ if aggregate_events.any?
28
24
  Sandthorn.save_events(
29
25
  aggregate_events,
30
26
  aggregate_id,
@@ -90,26 +86,17 @@ module Sandthorn
90
86
  unless events && !events.empty?
91
87
  raise Sandthorn::Errors::AggregateNotFound
92
88
  end
93
-
94
- if first_event_snapshot?(events)
95
- transformed_snapshot_event = events.first.merge(event_args: Sandthorn.deserialize_snapshot(events.first[:event_data]))
96
- events.shift
97
- end
98
89
 
99
- transformed_events = events.map do |e|
100
- e.merge(event_args: Sandthorn.deserialize(e[:event_data]))
101
- end
102
- aggregate_build ([transformed_snapshot_event] + transformed_events).compact
90
+ aggregate_build events
103
91
  end
104
92
 
105
93
  def new *args, &block
106
-
107
- aggregate = allocate
94
+ aggregate = create_new_empty_aggregate()
108
95
  aggregate.aggregate_base_initialize
109
96
  aggregate.aggregate_initialize
110
97
 
111
98
  aggregate.default_attributes
112
- aggregate.send :initialize, *args, &block
99
+ aggregate.send :initialize, *args, &block
113
100
  aggregate.send :set_aggregate_id, Sandthorn.generate_aggregate_id
114
101
 
115
102
  aggregate.aggregate_trace @@aggregate_trace_information do |aggr|
@@ -119,27 +106,26 @@ module Sandthorn
119
106
 
120
107
  end
121
108
 
122
-
123
-
124
109
  def aggregate_build events
125
- current_aggregate_version = 0
126
-
127
110
  if first_event_snapshot?(events)
128
- aggregate = start_build_from_snapshot events
129
- current_aggregate_version = aggregate.aggregate_originating_version
111
+ aggregate = events.first[:aggregate]
130
112
  events.shift
131
113
  else
132
114
  aggregate = create_new_empty_aggregate
133
115
  end
134
116
 
117
+ if events.any?
118
+ current_aggregate_version = events.last[:aggregate_version]
119
+ aggregate.send :set_orginating_aggregate_version!, current_aggregate_version
120
+ aggregate.send :set_current_aggregate_version!, current_aggregate_version
121
+ end
122
+
135
123
  attributes = build_instance_vars_from_events events
136
- current_aggregate_version = events.last[:aggregate_version] unless events.empty?
137
124
  aggregate.send :clear_aggregate_events
125
+
138
126
  aggregate.default_attributes
139
- aggregate.send :set_orginating_aggregate_version!, current_aggregate_version
140
- aggregate.send :set_current_aggregate_version!, current_aggregate_version
141
127
  aggregate.send :aggregate_initialize
142
-
128
+
143
129
  aggregate.send :set_instance_variables!, attributes
144
130
  aggregate
145
131
  end
@@ -159,7 +145,6 @@ module Sandthorn
159
145
  def build_instance_vars_from_events events
160
146
  events.each_with_object({}) do |event, instance_vars|
161
147
  event_args = event[:event_args]
162
- event_name = event[:event_name]
163
148
  attribute_deltas = event_args[:attribute_deltas]
164
149
  unless attribute_deltas.nil?
165
150
  deltas = attribute_deltas.each_with_object({}) do |delta, acc|
@@ -171,11 +156,7 @@ module Sandthorn
171
156
  end
172
157
 
173
158
  def first_event_snapshot? events
174
- events.first[:event_name].to_sym == :aggregate_set_from_snapshot
175
- end
176
-
177
- def start_build_from_snapshot events
178
- snapshot = events.first[:event_args][0]
159
+ events.first[:aggregate]
179
160
  end
180
161
 
181
162
  def create_new_empty_aggregate
@@ -13,39 +13,10 @@ module Sandthorn
13
13
  raise Errors::SnapshotError,
14
14
  "Can't take snapshot on object with unsaved events"
15
15
  end
16
-
17
- @aggregate_snapshot = {
18
- event_name: "aggregate_set_from_snapshot",
19
- event_args: [self],
20
- aggregate_version: @aggregate_current_event_version
21
- }
22
16
  end
23
17
 
24
18
  def save_snapshot
25
- unless aggregate_snapshot
26
- raise Errors::SnapshotError, "No snapshot has been created!"
27
- end
28
- @aggregate_snapshot[:event_data] = Sandthorn.serialize_snapshot @aggregate_snapshot[:event_args]
29
- @aggregate_snapshot[:event_args] = nil
30
- Sandthorn.save_snapshot(aggregate_snapshot: @aggregate_snapshot, aggregate_id: @aggregate_id, aggregate_type: self.class)
31
- @aggregate_snapshot = nil
32
- end
33
- private
34
- def aggregate_create_event_when_extended
35
- self.aggregate_snapshot!
36
- vars = extract_relevant_aggregate_instance_variables
37
- vars.each do |var_name|
38
- value = instance_variable_get var_name
39
- dump = Marshal.dump(value)
40
- store_aggregate_instance_variable var_name, dump
41
- end
42
-
43
- @aggregate_snapshot[:event_data] = Sandthorn
44
- .serialize_snapshot aggregate_snapshot[:event_args]
45
-
46
- @aggregate_snapshot[:event_args] = nil
47
- Sandthorn.save_snapshot aggregate_snapshot, aggregate_id
48
- @aggregate_snapshot = nil
19
+ Sandthorn.save_snapshot(self)
49
20
  end
50
21
  end
51
22
  end
@@ -1,3 +1,3 @@
1
1
  module Sandthorn
2
- VERSION = "0.10.3"
2
+ VERSION = "0.11.0"
3
3
  end
data/sandthorn.gemspec CHANGED
@@ -30,5 +30,5 @@ Gem::Specification.new do |spec|
30
30
  spec.add_development_dependency "autotest-standalone"
31
31
  spec.add_development_dependency "sqlite3"
32
32
  spec.add_development_dependency "coveralls"
33
- spec.add_development_dependency "sandthorn_driver_sequel", "~> 2.0"
33
+ spec.add_development_dependency "sandthorn_driver_sequel", ">= 3.0"
34
34
  end
@@ -87,7 +87,7 @@ module Sandthorn
87
87
  it "should set the values" do
88
88
  expect(subject.name).to eql "Mogge"
89
89
  expect(subject.sex).to eql "hen"
90
- expect{subject.writer}.to raise_error
90
+ expect{subject.writer}.to raise_error NoMethodError
91
91
  end
92
92
  end
93
93
 
@@ -117,12 +117,12 @@ module Sandthorn
117
117
 
118
118
  context "when changing writer (attr_writer)" do
119
119
  it "should raise error" do
120
- expect{dirty_object.change_writer "new_writer"}.to raise_error
120
+ expect{dirty_object.change_writer "new_writer"}.to raise_error NameError
121
121
  end
122
122
  end
123
123
 
124
124
  context "save" do
125
- it "should not have events on aggregete after save" do
125
+ it "should not have events on aggregate after save" do
126
126
  expect(dirty_object.save.aggregate_events.length).to eql 0
127
127
  end
128
128
 
@@ -147,7 +147,7 @@ module Sandthorn
147
147
  end
148
148
 
149
149
  it "should raise error if trying to find id that not exist" do
150
- expect{DirtyClass.find("666")}.to raise_error
150
+ expect{DirtyClass.find("666")}.to raise_error Sandthorn::Errors::AggregateNotFound
151
151
  end
152
152
  end
153
153
 
@@ -185,17 +185,10 @@ describe 'when generating state on an aggregate root' do
185
185
  expect(@account.unpaid_interest_balance).to be > 1000
186
186
  end
187
187
 
188
- it 'should store snapshot data in aggregate_snapshot' do
189
- expect(@account.aggregate_snapshot).to be_a(Hash)
190
- end
191
-
192
- it 'should store aggregate_version in aggregate_snapshot' do
193
- expect(@account.aggregate_snapshot[:aggregate_version]).to eql(@original_account.aggregate_current_event_version)
194
- end
195
188
 
196
189
  it 'should be able to load up from snapshot' do
197
190
 
198
- events = [@account.aggregate_snapshot]
191
+ events = [aggregate: @account]
199
192
  loaded = BankAccount.aggregate_build events
200
193
 
201
194
  expect(loaded.balance).to eql(@original_account.balance)
@@ -227,9 +220,7 @@ end
227
220
 
228
221
  describe 'when saving to repository' do
229
222
  let(:account) {a_test_account.extend Sandthorn::AggregateRootSnapshot}
230
- it 'should raise an error if trying to save before creating a snapshot' do
231
- expect(lambda {account.save_snapshot}).to raise_error (Sandthorn::Errors::SnapshotError)
232
- end
223
+
233
224
  it 'should not raise an error if snapshot was created' do
234
225
  account.save
235
226
  account.aggregate_snapshot!
@@ -243,7 +234,7 @@ describe 'when saving to repository' do
243
234
  end
244
235
 
245
236
  it 'should raise error if trying to create snapshot before events are saved on object' do
246
- expect(lambda {account.aggregate_snapshot!}).to raise_error
237
+ expect(lambda {account.aggregate_snapshot!}).to raise_error Sandthorn::Errors::SnapshotError
247
238
  end
248
239
 
249
240
  it 'should not raise an error if trying to create snapshot on object when events are saved' do
data/spec/spec_helper.rb CHANGED
@@ -40,14 +40,17 @@ def spec_db
40
40
  "sqlite://spec/db/sequel_driver.sqlite3"
41
41
  end
42
42
  def sqlite_store_setup
43
- url = spec_db
44
- driver = SandthornDriverSequel.driver_from_url(url: url)
43
+ url = spec_db
44
+
45
+ driver = SandthornDriverSequel.driver_from_url(url: url) do |conf|
46
+ conf.event_serializer = Proc.new { |data| YAML::dump(data) }
47
+ conf.event_deserializer = Proc.new { |data| YAML::load(data) }
48
+ conf.snapshot_serializer = Proc.new { |data| YAML::dump(data) }
49
+ conf.snapshot_deserializer = Proc.new { |data| YAML::load(data) }
50
+ end
51
+
45
52
  Sandthorn.configure do |c|
46
53
  c.event_store = driver
47
- c.serializer = Proc.new { |data| YAML::dump(data) }
48
- c.deserializer = Proc.new { |data| YAML::load(data) }
49
- c.snapshot_serializer = Proc.new { |data| YAML::dump(data) }
50
- c.snapshot_deserializer = Proc.new { |data| YAML::load(data) }
51
54
  end
52
55
  migrator = SandthornDriverSequel::Migration.new url: url
53
56
  SandthornDriverSequel.migrate_db url: url
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sandthorn
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.10.3
4
+ version: 0.11.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Lars Krantz
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2016-01-28 00:00:00.000000000 Z
13
+ date: 2016-02-11 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: bundler
@@ -156,16 +156,16 @@ dependencies:
156
156
  name: sandthorn_driver_sequel
157
157
  requirement: !ruby/object:Gem::Requirement
158
158
  requirements:
159
- - - "~>"
159
+ - - ">="
160
160
  - !ruby/object:Gem::Version
161
- version: '2.0'
161
+ version: '3.0'
162
162
  type: :development
163
163
  prerelease: false
164
164
  version_requirements: !ruby/object:Gem::Requirement
165
165
  requirements:
166
- - - "~>"
166
+ - - ">="
167
167
  - !ruby/object:Gem::Version
168
- version: '2.0'
168
+ version: '3.0'
169
169
  description: Event sourcing gem
170
170
  email:
171
171
  - lars.krantz@alaz.se