ruby_cqrs 0.2.0 → 0.2.1

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: a0bff53f5c549da4478fd01b6c2cbfcf37f2c113
4
- data.tar.gz: 6b699a6579e93f27d6af1f0305a90f941bddf1d9
3
+ metadata.gz: a5f70e7b70c21215981195e374595fce852f0d94
4
+ data.tar.gz: 5312d18d87f660591396ca99cc120edb5e63bfb1
5
5
  SHA512:
6
- metadata.gz: 54d999384f32a945152bf47b482562212a660bb824f0dac7c0495b5d7461adac974919931ec37ad73a8d18a01e619f9097318e23a5898336ef598c119aebd8b6
7
- data.tar.gz: 885545a8f2118cee2aa1957967b011225a6360607bd5669307c260d06baf05c7eccbc640fb288521ec39f39df7cba7fc0b01fd993f2bca3304caa3029ee4fb4a
6
+ metadata.gz: 95dbd4d1ebc007450eba00a2f7bc4e8cf2dd47b439299bed29ee1bea5138b09e3058a68528f214345ae7cfdca02df8b78dead78037e810e5f6dcc5fb1a694a41
7
+ data.tar.gz: 0f4ea2e1eea528a598fa1e34a760994a51276e79c929a7078767ae7e5a4c31afffe5fad7c732ce1c9988618dd5a78a98e029a4ea955ced1c6a30550902dbea37
data/README.md CHANGED
@@ -1,8 +1,8 @@
1
- [![Build Status](https://travis-ci.org/iravench/ruby_cqrs.svg?branch=master)](https://travis-ci.org/iravench/ruby_cqrs) [![Code Climate](https://codeclimate.com/github/iravench/ruby_cqrs/badges/gpa.svg)](https://codeclimate.com/github/iravench/ruby_cqrs) [![Test Coverage](https://codeclimate.com/github/iravench/ruby_cqrs/badges/coverage.svg)](https://codeclimate.com/github/iravench/ruby_cqrs)
1
+ [![Gem Version](https://badge.fury.io/rb/ruby_cqrs.svg)](http://badge.fury.io/rb/ruby_cqrs) [![Build Status](https://travis-ci.org/iravench/ruby_cqrs.svg?branch=master)](https://travis-ci.org/iravench/ruby_cqrs) [![Code Climate](https://codeclimate.com/github/iravench/ruby_cqrs/badges/gpa.svg)](https://codeclimate.com/github/iravench/ruby_cqrs) [![Test Coverage](https://codeclimate.com/github/iravench/ruby_cqrs/badges/coverage.svg)](https://codeclimate.com/github/iravench/ruby_cqrs)
2
2
 
3
3
  # RubyCqrs
4
4
 
5
- A Ruby implementation of CQRS, using event sourcing.
5
+ A Ruby implementation of CQRS, using event sourcing. go wiki cqrs for more information.
6
6
 
7
7
  ## Installation
8
8
 
@@ -23,14 +23,14 @@ module RubyCqrs
23
23
  def load_from state
24
24
  sorted_events = state[:events].sort { |x, y| x.version <=> y.version }
25
25
  @aggregate_id = state[:aggregate_id]
26
- try_load_snapshot_from state
26
+ try_apply_snapshot_in state
27
27
  sorted_events.each do |event|
28
28
  apply(event)
29
29
  @source_version += 1
30
30
  end
31
31
  end
32
32
 
33
- def try_load_snapshot_from state
33
+ def try_apply_snapshot_in state
34
34
  if state.has_key? :snapshot and self.is_a? Snapshotable
35
35
  self.send :apply_snapshot, state[:snapshot][:state]
36
36
  @version = state[:snapshot][:version]
@@ -42,7 +42,7 @@ module RubyCqrs
42
42
  def get_changes
43
43
  return nil unless @pending_events.size > 0
44
44
  changes = {
45
- :events => @pending_events,
45
+ :events => @pending_events.dup,
46
46
  :aggregate_id => @aggregate_id,
47
47
  :aggregate_type => self.class.name,
48
48
  :expecting_source_version => @source_version,
@@ -37,7 +37,7 @@ module RubyCqrs
37
37
  end
38
38
 
39
39
  def create_instance_from state
40
- try_decode_from state
40
+ try_decode_serialized_from state
41
41
  instance = state[:aggregate_type].constantize.new
42
42
  instance.send(:load_from, state)
43
43
  instance
@@ -68,17 +68,17 @@ module RubyCqrs
68
68
  raise ArgumentError unless aggregate.is_a? Aggregate
69
69
  aggregate_change = aggregate.send(:get_changes)
70
70
  next if aggregate_change.nil?
71
- try_encode_from aggregate_change
71
+ try_encode_serializable_in aggregate_change
72
72
  product << aggregate_change
73
73
  end
74
74
  to_return
75
75
  end
76
76
 
77
- def try_decode_from state
77
+ def try_decode_serialized_from state
78
78
  state[:snapshot] = decode_snapshot_state_from state[:snapshot]\
79
79
  if state.has_key? :snapshot
80
80
 
81
- state[:events].map! { |event_record| decode_event_from event_record }\
81
+ state[:events] = state[:events].map { |event_record| decode_event_from event_record }\
82
82
  if state[:events].size > 0
83
83
  end
84
84
 
@@ -94,7 +94,7 @@ module RubyCqrs
94
94
  decoded_event
95
95
  end
96
96
 
97
- def try_encode_from change
97
+ def try_encode_serializable_in change
98
98
  if change.has_key? :snapshot
99
99
  encoded_snapshot = encode_data_from change[:snapshot][:state]
100
100
  change[:snapshot] = { :state_type => change[:snapshot][:state_type],
@@ -1,3 +1,3 @@
1
1
  module RubyCqrs # :nodoc:
2
- VERSION = '0.2.0'
2
+ VERSION = '0.2.1'
3
3
  end
@@ -1,25 +1,29 @@
1
1
  require_relative('../spec_helper.rb')
2
2
 
3
+ # after installing the gem, require its features
4
+ require('ruby_cqrs')
3
5
  # define your domain object
4
6
  class Customer
5
- # mark as a domain object
7
+ # mark your domain object as an aggregate
6
8
  include RubyCqrs::Domain::Aggregate
7
- # makr as snapshotable
8
- # the default setting is when more 30 events are raised
9
- # after the last snapshot is taken, a new snapshot is generated
10
- # change the default by defining SNAPSHOT_THRESHOLD = 20(or other number)
9
+ # optionally, also makr as snapshotable in order to avoid heavy events reading pressure
10
+ # if your aggregate won't be generating much events, you can just ignore this
11
+ # the default setting is thant when over 30 events get raised after the last snapshot taken,
12
+ # a new snapshot will be generated upon calling aggregate_repository.save
13
+ # change this default value by defining SNAPSHOT_THRESHOLD = 20(or other number)
11
14
  include RubyCqrs::Domain::Snapshotable
12
15
 
13
16
  attr_reader :name, :credit
14
17
 
15
18
  # unfortunately, you should not try to define your own initialize method
16
- # at the time being, it could potentially cause error when the aggregate
17
- # repository try to load your domain object back.
19
+ # at the time being, it could potentially cause error with aggregate_repository
20
+ # when it tries to instantiate an aggregate back to live.
21
+ # Still looking for better way to do this.
18
22
 
19
- # define your domain object's behaviors
23
+ # define domain behaviors
20
24
  def create_profile name, credit
21
- # again, this is like your normal initialize method,
22
- # it should get called only once...
25
+ # again, this one method kinda serve as your normal initialize method here,
26
+ # which means it should be called once only
23
27
  raise RuntimeError.new('the profile has already been created') unless @name.nil?
24
28
  raise AgumentError if name.nil?
25
29
  raise AgumentError if credit < 100
@@ -36,9 +40,8 @@ class Customer
36
40
  end
37
41
 
38
42
  private
39
- # when an event is raised or replayed,
40
- # these methods will get called automatically,
41
- # manage the domain object's internal state here
43
+ # when an event gets raised or replayed, these on_ methods will be called automatically,
44
+ # with the events's detail information, you can manage the aggregate's internal state
42
45
  def on_customer_created customer_created
43
46
  @name = customer_created.name
44
47
  @credit = customer_created.credit
@@ -48,9 +51,9 @@ private
48
51
  @credit -= product_ordered.cost
49
52
  end
50
53
 
51
- # when a domain object is marked as snapshotable,
52
- # you must implement these two methods to record the object's vital state
53
- # and apply the snapshot in order to restore your object's data respectively
54
+ # when an aggregate is marked as snapshotable,
55
+ # following two methods must be implemented in order to record and restore
56
+ # the aggregate's vital state respectively,
54
57
  def take_a_snapshot
55
58
  CustomerSnapshot.new(:name => @name, :credit => @credit)
56
59
  end
@@ -61,10 +64,10 @@ private
61
64
  end
62
65
  end
63
66
 
64
- # define a snapshot to keep all vital state of your domain object
65
- # the repository will use the latest snapshot it can find
66
- # and events happened after the snapshot has been taken
67
- # to recreate your domain object
67
+ # define a snapshot to keep all vital state
68
+ # the repository will look for the latest snapshot it can find, plus
69
+ # all events happened right after when that particular snapshot gets taken
70
+ # in order to revive your aggregate instance
68
71
  class CustomerSnapshot
69
72
  include Beefcake::Message
70
73
  include RubyCqrs::Domain::Snapshot
@@ -73,7 +76,9 @@ class CustomerSnapshot
73
76
  required :credit, :int32, 2
74
77
  end
75
78
 
76
- # defined the events your domain object will raise
79
+ # defined the events your aggregate will raise
80
+ # your domain's event collection can be defined in a way easy to share among teams
81
+ # which enables smooth integration through event logs
77
82
  class CustomerCreated
78
83
  include RubyCqrs::Domain::Event
79
84
  include Beefcake::Message
@@ -89,15 +94,19 @@ class ProductOrdered
89
94
  required :cost, :int32, 1
90
95
  end
91
96
 
92
- # here goes the spec of how you can use the domain object
97
+ # here goes the spec of how you can use previously defined aggregate objects
93
98
  describe 'Your awesome customer domain objects powered by ruby_cqrs' do
94
- # a context related to the command, which is specific to your problem domain
95
- # normally, when a command arrives, one or more domain objects are created or loaded
99
+ # a context related to a command, which is specific to your problem domain
100
+ # normally, when the command arrives, one or more domain objects are activated
96
101
  # in order to fulfill the command's request
102
+ #
103
+ # a command context then encapsulates any information which could be of importance
104
+ # but not part of your current domain, you can later choose to persist all or
105
+ # part of the context to support further processing or integration.
97
106
  let(:command_context) {}
98
- # you should implement your own event_store in order to persist your aggregate state
99
- # you should read about the InMemoryEventStore implementation
100
- # and make sure your response with correct data format
107
+ # you should implement your own event_store in order to persist aggregate state
108
+ # you can read about the InMemoryEventStore implementation
109
+ # to understand the data format pass in and out
101
110
  let(:event_store) { RubyCqrs::Data::InMemoryEventStore.new }
102
111
  # every time when a command arrives,
103
112
  # an aggregate repository gets created with related command context and event_store implementation
@@ -160,7 +169,7 @@ describe 'Your awesome customer domain objects powered by ruby_cqrs' do
160
169
  (1..30).each { lucy.order_product(10) }
161
170
  repository.save lucy
162
171
 
163
- # well, you just have to trust a snapshot has been generated :)
172
+ # well, you'll just have to trust me a snapshot has been generated :)
164
173
  end
165
174
 
166
175
  it 'finds an old customer instance back from snapshot' do
@@ -168,7 +177,7 @@ describe 'Your awesome customer domain objects powered by ruby_cqrs' do
168
177
  repository.save lucy
169
178
  lucy_reload = repository.find_by lucy.aggregate_id
170
179
 
171
- # again, it's been loaded from a snapshot ;)
180
+ # again, a snapshot has been applied to gain you a bit performance boost ;)
172
181
 
173
182
  expect(lucy_reload.name).to eq('Lucy')
174
183
  expect(lucy_reload.credit).to eq(700)
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruby_cqrs
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Raven Chen
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-04-13 00:00:00.000000000 Z
11
+ date: 2015-04-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: uuidtools
@@ -107,7 +107,7 @@ rubyforge_project:
107
107
  rubygems_version: 2.4.6
108
108
  signing_key:
109
109
  specification_version: 4
110
- summary: ruby_cqrs-0.2.0
110
+ summary: ruby_cqrs-0.2.1
111
111
  test_files:
112
112
  - spec/feature/basic_usage_spec.rb
113
113
  - spec/feature/snapshot_spec.rb