event_sourced_record 0.1.3 → 0.2.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/CHANGELOG.md +9 -0
- data/lib/event_sourced_record/calculator.rb +12 -4
- data/lib/event_sourced_record/event.rb +5 -0
- data/lib/event_sourced_record/version.rb +1 -1
- data/lib/generators/event_sourced_record/event_sourced_record_generator.rb +1 -1
- data/test/event_sourced_record/event_test.rb +17 -0
- data/test/generators/event_generator_test.rb +4 -1
- data/test/generators/event_sourced_record_generator_test.rb +1 -1
- data/test/test_helper.rb +39 -0
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b0ee2af5ab48feddf17d097471e7298e444b261f
|
4
|
+
data.tar.gz: 7b9d4960dfbaaae80abf9f93ed8e640cb1503d01
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3c596cb4d97f385ee2827a876f3d1ced7fc180ec80a03ea174aeafceb85269c42662190d486cdd426b6cf561372d3715b5743d1eea7bbea8500d61adb658acd2
|
7
|
+
data.tar.gz: b570432fd7e2db6d8fb072031d17475e7bc7579c5beaab175c5d4c752bbba7451700731ddde53f86a8761dc2d417b2a1d245e18236caf34c4de02fa26c5af9bf
|
data/CHANGELOG.md
ADDED
@@ -0,0 +1,9 @@
|
|
1
|
+
[[[0.2.0]] - Feb 23 2015]
|
2
|
+
|
3
|
+
* BUGFIX - allow multiple calculators (#11).
|
4
|
+
* Included the configuration for the `data` column in the generated Event class
|
5
|
+
(#9).
|
6
|
+
* Made Event instances immutable (#8).
|
7
|
+
* Added `occurred_at` to generated events, which will be used by the calculator
|
8
|
+
for ordering events. If `occurred_at` is not defined, `created_at` will be
|
9
|
+
used instead (#6).
|
@@ -1,10 +1,10 @@
|
|
1
1
|
class EventSourcedRecord::Calculator
|
2
2
|
def self.events(*event_symbols)
|
3
|
-
|
3
|
+
@event_symbols = event_symbols
|
4
4
|
end
|
5
5
|
|
6
6
|
def self.event_classes
|
7
|
-
|
7
|
+
@event_symbols.map { |sym|
|
8
8
|
Module.const_get(sym.to_s.singularize.camelize)
|
9
9
|
}
|
10
10
|
end
|
@@ -88,13 +88,21 @@ class EventSourcedRecord::Calculator
|
|
88
88
|
conditions = {projection_name + '_id' => projection.id} if projection
|
89
89
|
end
|
90
90
|
conditions ? event_class.where(conditions).to_a : []
|
91
|
-
}.flatten.sort_by(
|
91
|
+
}.flatten.sort_by{ |evt| occurrence_time(evt) }.reject { |evt|
|
92
92
|
if last_event_time
|
93
|
-
evt
|
93
|
+
occurrence_time(evt) > last_event_time
|
94
94
|
end
|
95
95
|
}
|
96
96
|
end
|
97
97
|
|
98
|
+
def occurrence_time(event)
|
99
|
+
if event.respond_to?(:occurred_at) && event.occurred_at
|
100
|
+
event.occurred_at
|
101
|
+
else
|
102
|
+
event.created_at
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
98
106
|
def uuid_field
|
99
107
|
projection_name + '_uuid'
|
100
108
|
end
|
@@ -9,6 +9,7 @@ module EventSourcedRecord::Event
|
|
9
9
|
model.after_initialize :ensure_data
|
10
10
|
model.after_initialize :ensure_projection_uuid
|
11
11
|
model.after_initialize :lock_event_type
|
12
|
+
model.before_validation :ensure_occurred_at, on: :create
|
12
13
|
model.validates :event_type, presence: true
|
13
14
|
model.validate :validate_corrent_event_type
|
14
15
|
model.validate :validate_by_event_type
|
@@ -56,6 +57,10 @@ module EventSourcedRecord::Event
|
|
56
57
|
@event_type_locked = true
|
57
58
|
end
|
58
59
|
|
60
|
+
def ensure_occurred_at
|
61
|
+
self.occurred_at = Time.now unless occurred_at
|
62
|
+
end
|
63
|
+
|
59
64
|
def method_missing(meth, *args, &block)
|
60
65
|
if event_type_config && event_type_config.attributes.include?(meth)
|
61
66
|
ensure_data
|
@@ -13,7 +13,7 @@ class EventSourcedRecord::EventSourcedRecordGenerator < Rails::Generators::Named
|
|
13
13
|
def create_event
|
14
14
|
arguments = [
|
15
15
|
"#{file_name}_uuid:string:index", "event_type:string",
|
16
|
-
"data:text", "created_at:datetime"
|
16
|
+
"data:text", "created_at:datetime", "occurred_at:datetime"
|
17
17
|
].join(' ')
|
18
18
|
generate "event_sourced_record:event", "#{file_name}_event #{arguments}"
|
19
19
|
end
|
@@ -119,4 +119,21 @@ class EventSourcedRecord::EventTest < MiniTest::Unit::TestCase
|
|
119
119
|
event.touch
|
120
120
|
end
|
121
121
|
end
|
122
|
+
|
123
|
+
def test_occurred_at_is_set_if_not_specified
|
124
|
+
event = SubscriptionEvent.creation.create!(
|
125
|
+
bottles_per_shipment: 1, bottles_purchased: 6, user_id: 999
|
126
|
+
)
|
127
|
+
|
128
|
+
assert event.occurred_at
|
129
|
+
end
|
130
|
+
|
131
|
+
def test_occurred_at_can_be_specified
|
132
|
+
event = SubscriptionEvent.creation.new(
|
133
|
+
occurred_at: Time.new(2003, 1, 24, 11, 33), bottles_per_shipment: 1,
|
134
|
+
bottles_purchased: 6, user_id: 999
|
135
|
+
)
|
136
|
+
|
137
|
+
assert_equal(Time.new(2003, 1, 24, 11, 33), event.occurred_at)
|
138
|
+
end
|
122
139
|
end
|
@@ -16,6 +16,7 @@ class EventSourcedRecord::EventGeneratorTest < Rails::Generators::TestCase
|
|
16
16
|
event_type:string
|
17
17
|
data:text
|
18
18
|
created_at:datetime
|
19
|
+
occurred_at:datetime
|
19
20
|
)
|
20
21
|
end
|
21
22
|
|
@@ -23,11 +24,13 @@ class EventSourcedRecord::EventGeneratorTest < Rails::Generators::TestCase
|
|
23
24
|
ar_major_version = ActiveRecord::VERSION::MAJOR
|
24
25
|
if ar_major_version >= 4
|
25
26
|
assert @generate_calls['migration'].include?(
|
26
|
-
"create_subscription_events subscription_uuid:string:index event_type:string data:text created_at:datetime"
|
27
|
+
"create_subscription_events subscription_uuid:string:index event_type:string data:text created_at:datetime occurred_at:datetime"
|
27
28
|
)
|
28
29
|
else
|
29
30
|
assert_migration("db/migrate/create_subscription_events.rb") do |contents|
|
30
31
|
assert_match(/t.string :event_type/, contents)
|
32
|
+
assert_match(/t.datetime :created_at/, contents)
|
33
|
+
assert_match(/t.datetime :occurred_at/, contents)
|
31
34
|
end
|
32
35
|
end
|
33
36
|
end
|
@@ -20,7 +20,7 @@ class EventSourcedRecord::EventSourcedRecordGeneratorTest < Rails::Generators::T
|
|
20
20
|
|
21
21
|
test "calls the event generator" do
|
22
22
|
assert @generate_calls['event_sourced_record:event'].include?(
|
23
|
-
"shampoo_subscription_event shampoo_subscription_uuid:string:index event_type:string data:text created_at:datetime"
|
23
|
+
"shampoo_subscription_event shampoo_subscription_uuid:string:index event_type:string data:text created_at:datetime occurred_at:datetime"
|
24
24
|
)
|
25
25
|
end
|
26
26
|
|
data/test/test_helper.rb
CHANGED
@@ -38,6 +38,7 @@ silence_stream(STDOUT) do
|
|
38
38
|
t.string "event_type"
|
39
39
|
t.text "data"
|
40
40
|
t.datetime "created_at"
|
41
|
+
t.datetime "occurred_at"
|
41
42
|
end
|
42
43
|
|
43
44
|
create_table "subscriptions", force: true do |t|
|
@@ -46,6 +47,19 @@ silence_stream(STDOUT) do
|
|
46
47
|
t.integer "bottles_left"
|
47
48
|
t.string "uuid"
|
48
49
|
end
|
50
|
+
|
51
|
+
create_table "bottle_events", force: true do |t|
|
52
|
+
t.string "bottle_uuid"
|
53
|
+
t.string "event_type"
|
54
|
+
t.text "data"
|
55
|
+
t.datetime "created_at"
|
56
|
+
end
|
57
|
+
|
58
|
+
create_table "bottles", force: true do |t|
|
59
|
+
t.integer "volume"
|
60
|
+
t.decimal "cost_price"
|
61
|
+
t.string "uuid"
|
62
|
+
end
|
49
63
|
end
|
50
64
|
end
|
51
65
|
|
@@ -90,3 +104,28 @@ class SubscriptionCalculator < EventSourcedRecord::Calculator
|
|
90
104
|
@subscription.bottles_left -= shipment.num_bottles
|
91
105
|
end
|
92
106
|
end
|
107
|
+
|
108
|
+
class BottleEvent < ActiveRecord::Base
|
109
|
+
include EventSourcedRecord::Event
|
110
|
+
|
111
|
+
serialize :data
|
112
|
+
|
113
|
+
event_type :purchase do
|
114
|
+
attributes :volume, :cost_price
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
class Bottle < ActiveRecord::Base
|
119
|
+
has_many :bottle_events
|
120
|
+
|
121
|
+
validates :uuid, uniqueness: true
|
122
|
+
end
|
123
|
+
|
124
|
+
class BottleCalculator < EventSourcedRecord::Calculator
|
125
|
+
events :bottle_events, :shipments
|
126
|
+
|
127
|
+
def advance_purchase(event)
|
128
|
+
@bottle.volume = event.volume
|
129
|
+
@bottle.cost_price = event.cost_price
|
130
|
+
end
|
131
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: event_sourced_record
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Francis Hwang
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-02-
|
11
|
+
date: 2015-02-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activemodel
|
@@ -160,6 +160,7 @@ files:
|
|
160
160
|
- ".gitignore"
|
161
161
|
- ".travis.yml"
|
162
162
|
- Appraisals
|
163
|
+
- CHANGELOG.md
|
163
164
|
- Gemfile
|
164
165
|
- Getting_Started.md
|
165
166
|
- LICENSE.txt
|