ruby_event_store-rom 2.1.0 → 2.3.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/README.md +44 -0
- data/lib/ruby_event_store/rom/changesets/update_events.rb +1 -1
- data/lib/ruby_event_store/rom/event_repository.rb +11 -13
- data/lib/ruby_event_store/rom/relations/events.rb +24 -8
- data/lib/ruby_event_store/rom/relations/stream_entries.rb +30 -10
- data/lib/ruby_event_store/rom/repositories/events.rb +30 -16
- data/lib/ruby_event_store/rom/repositories/stream_entries.rb +2 -2
- data/lib/ruby_event_store/rom/unit_of_work.rb +1 -1
- data/lib/ruby_event_store/rom/version.rb +1 -1
- metadata +6 -9
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: fd644498c9073a4fedae61d6bbc305373ce49f3b5a5dc474798905b2928b5013
|
|
4
|
+
data.tar.gz: 41947bff3903557aa6d816a5807165613c513f99fa8d4b97e84005628c4f6b31
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: e572f34403a3924f2ed6343b2bdb690d31d7cdb8e85f7eff0c44caafb3ece603224e7ad6dae950b2396124f709694904d539d811cc58847b6fa2e9aa4f04e9dd
|
|
7
|
+
data.tar.gz: 75a35e00b8bb953bd81c4a9a4b95596db5c555b4d813e6717ff5767b6bced436f346f5d5d09debcf044f16c7e71a585da132ea5e8ac32f56a1a97b9204ed342b
|
data/README.md
CHANGED
|
@@ -7,3 +7,47 @@ A Ruby Object Model (ROM) implementation of events repository for [Ruby Event St
|
|
|
7
7
|
This version of the ROM adapter supports [rom-sql](https://github.com/rom-rb/rom-sql) at this time. It is an alternative to the ActiveRecord `EventRepository` implementation used in `rails_event_store` gem.
|
|
8
8
|
|
|
9
9
|
[Read the docs to get started.](http://railseventstore.org/docs/repository/)
|
|
10
|
+
|
|
11
|
+
## Setup
|
|
12
|
+
|
|
13
|
+
### Rake tasks
|
|
14
|
+
|
|
15
|
+
Add to your `Rakefile`
|
|
16
|
+
|
|
17
|
+
```ruby
|
|
18
|
+
require "ruby_event_store/rom/rake_task"
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
### Database migration
|
|
22
|
+
|
|
23
|
+
A migration template can be found in [db/migrate/20210806000000_create_ruby_event_store_tables.rb](db/migrate/20210806000000_create_ruby_event_store_tables.rb).
|
|
24
|
+
|
|
25
|
+
You can choose the type of the `data` and `metadata` columns by using the `DATA_TYPE` environment variable:
|
|
26
|
+
|
|
27
|
+
```shell
|
|
28
|
+
rake db:migrate DATA_TYPE='text' # or
|
|
29
|
+
rake db:migrate DATA_TYPE='json' # or
|
|
30
|
+
rake db:migrate DATA_TYPE='jsonb'
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
### Application
|
|
34
|
+
|
|
35
|
+
```ruby
|
|
36
|
+
# config/initializers/ruby_event_store.rb
|
|
37
|
+
|
|
38
|
+
config = ROM::Configuration.new(:sql, ENV.fetch("DATABASE_URL"))
|
|
39
|
+
RES_ROM_CONTAINER = RubyEventStore::ROM.setup(config)
|
|
40
|
+
|
|
41
|
+
repository = RubyEventStore::ROM::EventRepository.new(
|
|
42
|
+
rom: RES_ROM_CONTAINER,
|
|
43
|
+
serializer: JSON # this setting is optional. Recommended when `data` and `metadata` are json(b) columns.
|
|
44
|
+
)
|
|
45
|
+
|
|
46
|
+
event_store = RubyEventStore::Client.new(repository: repository)
|
|
47
|
+
|
|
48
|
+
event_store.subscribe_to_all_events(RubyEventStore::LinkByCausationId.new(event_store: event_store))
|
|
49
|
+
event_store.subscribe_to_all_events(RubyEventStore::LinkByCorrelationId.new(event_store: event_store))
|
|
50
|
+
event_store.subscribe_to_all_events(RubyEventStore::LinkByEventType.new(event_store: event_store))
|
|
51
|
+
|
|
52
|
+
EVENT_STORE = event_store
|
|
53
|
+
```
|
|
@@ -35,7 +35,7 @@ module RubyEventStore
|
|
|
35
35
|
.dataset
|
|
36
36
|
.insert_conflict(
|
|
37
37
|
target: :event_id,
|
|
38
|
-
update: UPSERT_COLUMNS.each_with_object({}) { |column, memo| memo[column] = Sequel[:excluded][column] }
|
|
38
|
+
update: UPSERT_COLUMNS.each_with_object({}) { |column, memo| memo[column] = Sequel[:excluded][column] },
|
|
39
39
|
)
|
|
40
40
|
.multi_insert(to_a)
|
|
41
41
|
end
|
|
@@ -17,12 +17,11 @@ module RubyEventStore
|
|
|
17
17
|
handle_unique_violation do
|
|
18
18
|
@unit_of_work.call do |changesets|
|
|
19
19
|
changesets << @events.create_changeset(serialized_records)
|
|
20
|
-
changesets <<
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
)
|
|
20
|
+
changesets << @stream_entries.create_changeset(
|
|
21
|
+
event_ids,
|
|
22
|
+
stream,
|
|
23
|
+
@stream_entries.resolve_version(stream, expected_version),
|
|
24
|
+
)
|
|
26
25
|
end
|
|
27
26
|
end
|
|
28
27
|
|
|
@@ -34,12 +33,11 @@ module RubyEventStore
|
|
|
34
33
|
|
|
35
34
|
handle_unique_violation do
|
|
36
35
|
@unit_of_work.call do |changesets|
|
|
37
|
-
changesets <<
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
)
|
|
36
|
+
changesets << @stream_entries.create_changeset(
|
|
37
|
+
event_ids,
|
|
38
|
+
stream,
|
|
39
|
+
@stream_entries.resolve_version(stream, expected_version),
|
|
40
|
+
)
|
|
43
41
|
end
|
|
44
42
|
end
|
|
45
43
|
|
|
@@ -65,7 +63,7 @@ module RubyEventStore
|
|
|
65
63
|
def has_event?(event_id)
|
|
66
64
|
@events.exist?(event_id)
|
|
67
65
|
rescue Sequel::DatabaseError => doh
|
|
68
|
-
raise doh unless
|
|
66
|
+
raise doh unless /PG::InvalidTextRepresentation.*uuid/.match?(doh.message)
|
|
69
67
|
false
|
|
70
68
|
end
|
|
71
69
|
|
|
@@ -34,20 +34,36 @@ module RubyEventStore
|
|
|
34
34
|
where(event_type: types)
|
|
35
35
|
end
|
|
36
36
|
|
|
37
|
-
def newer_than(time)
|
|
38
|
-
|
|
37
|
+
def newer_than(time, time_sort_by)
|
|
38
|
+
if time_sort_by == :as_of
|
|
39
|
+
where { |r| string.coalesce(r.events[:valid_at], r.events[:created_at]) > time.localtime }
|
|
40
|
+
else
|
|
41
|
+
where { |r| r.events[:created_at] > time.localtime }
|
|
42
|
+
end
|
|
39
43
|
end
|
|
40
44
|
|
|
41
|
-
def newer_than_or_equal(time)
|
|
42
|
-
|
|
45
|
+
def newer_than_or_equal(time, time_sort_by)
|
|
46
|
+
if time_sort_by == :as_of
|
|
47
|
+
where { |r| string.coalesce(r.events[:valid_at], r.events[:created_at]) >= time.localtime }
|
|
48
|
+
else
|
|
49
|
+
where { |r| r.events[:created_at] >= time.localtime }
|
|
50
|
+
end
|
|
43
51
|
end
|
|
44
52
|
|
|
45
|
-
def older_than(time)
|
|
46
|
-
|
|
53
|
+
def older_than(time, time_sort_by)
|
|
54
|
+
if time_sort_by == :as_of
|
|
55
|
+
where { |r| string.coalesce(r.events[:valid_at], r.events[:created_at]) < time.localtime }
|
|
56
|
+
else
|
|
57
|
+
where { |r| r.events[:created_at] < time.localtime }
|
|
58
|
+
end
|
|
47
59
|
end
|
|
48
60
|
|
|
49
|
-
def older_than_or_equal(time)
|
|
50
|
-
|
|
61
|
+
def older_than_or_equal(time, time_sort_by)
|
|
62
|
+
if time_sort_by == :as_of
|
|
63
|
+
where { |r| string.coalesce(r.events[:valid_at], r.events[:created_at]) <= time.localtime }
|
|
64
|
+
else
|
|
65
|
+
where { |r| r.events[:created_at] <= time.localtime }
|
|
66
|
+
end
|
|
51
67
|
end
|
|
52
68
|
|
|
53
69
|
DIRECTION_MAP = { forward: %i[asc > <], backward: %i[desc < >] }.freeze
|
|
@@ -23,7 +23,7 @@ module RubyEventStore
|
|
|
23
23
|
end
|
|
24
24
|
|
|
25
25
|
def by_event_type(types)
|
|
26
|
-
|
|
26
|
+
join_events.where(event_type: types)
|
|
27
27
|
end
|
|
28
28
|
|
|
29
29
|
def by_stream_and_event_id(stream, event_id)
|
|
@@ -34,20 +34,36 @@ module RubyEventStore
|
|
|
34
34
|
by_stream(stream).select(:position).order(Sequel.desc(:position)).first
|
|
35
35
|
end
|
|
36
36
|
|
|
37
|
-
def newer_than(time)
|
|
38
|
-
|
|
37
|
+
def newer_than(time, time_sort_by)
|
|
38
|
+
if time_sort_by == :as_of
|
|
39
|
+
join_events.where { |r| string.coalesce(r.events[:valid_at], r.events[:created_at]) > time.localtime }
|
|
40
|
+
else
|
|
41
|
+
join_events.where { |r| r.events[:created_at] > time.localtime }
|
|
42
|
+
end
|
|
39
43
|
end
|
|
40
44
|
|
|
41
|
-
def newer_than_or_equal(time)
|
|
42
|
-
|
|
45
|
+
def newer_than_or_equal(time, time_sort_by)
|
|
46
|
+
if time_sort_by == :as_of
|
|
47
|
+
join_events.where { |r| string.coalesce(r.events[:valid_at], r.events[:created_at]) >= time.localtime }
|
|
48
|
+
else
|
|
49
|
+
join_events.where { |r| r.events[:created_at] >= time.localtime }
|
|
50
|
+
end
|
|
43
51
|
end
|
|
44
52
|
|
|
45
|
-
def older_than(time)
|
|
46
|
-
|
|
53
|
+
def older_than(time, time_sort_by)
|
|
54
|
+
if time_sort_by == :as_of
|
|
55
|
+
join_events.where { |r| string.coalesce(r.events[:valid_at], r.events[:created_at]) < time.localtime }
|
|
56
|
+
else
|
|
57
|
+
join_events.where { |r| r.events[:created_at] < time.localtime }
|
|
58
|
+
end
|
|
47
59
|
end
|
|
48
60
|
|
|
49
|
-
def older_than_or_equal(time)
|
|
50
|
-
|
|
61
|
+
def older_than_or_equal(time, time_sort_by)
|
|
62
|
+
if time_sort_by == :as_of
|
|
63
|
+
join_events.where { |r| string.coalesce(r.events[:valid_at], r.events[:created_at]) <= time.localtime }
|
|
64
|
+
else
|
|
65
|
+
join_events.where { |r| r.events[:created_at] <= time.localtime }
|
|
66
|
+
end
|
|
51
67
|
end
|
|
52
68
|
|
|
53
69
|
DIRECTION_MAP = { forward: %i[asc > <], backward: %i[desc < >] }.freeze
|
|
@@ -74,9 +90,13 @@ module RubyEventStore
|
|
|
74
90
|
if event_order_columns.empty?
|
|
75
91
|
query.order { |r| stream_order_columns.map { |c| r[:stream_entries][c].public_send(order) } }
|
|
76
92
|
else
|
|
77
|
-
query.
|
|
93
|
+
query.join_events.order { |r| event_order_columns.map { |c| r.events[c].public_send(order) } }
|
|
78
94
|
end
|
|
79
95
|
end
|
|
96
|
+
|
|
97
|
+
def join_events
|
|
98
|
+
dataset.opts[:join]&.map(&:table)&.include?(events.dataset.first_source_table) ? self : join(:events)
|
|
99
|
+
end
|
|
80
100
|
end
|
|
81
101
|
end
|
|
82
102
|
end
|
|
@@ -37,7 +37,7 @@ module RubyEventStore
|
|
|
37
37
|
BatchEnumerator.new(
|
|
38
38
|
specification.batch_size,
|
|
39
39
|
specification.limit,
|
|
40
|
-
->(offset, limit) { query_builder(serializer, query, offset: offset, limit: limit).to_ary }
|
|
40
|
+
->(offset, limit) { query_builder(serializer, query, offset: offset, limit: limit).to_ary },
|
|
41
41
|
).each
|
|
42
42
|
else
|
|
43
43
|
query = query_builder(serializer, query, limit: (specification.limit if specification.limit?))
|
|
@@ -65,6 +65,18 @@ module RubyEventStore
|
|
|
65
65
|
|
|
66
66
|
protected
|
|
67
67
|
|
|
68
|
+
def find_event_id_in_stream(specification_event_id, specification_stream_name)
|
|
69
|
+
stream_entries.by_stream_and_event_id(specification_stream_name, specification_event_id).fetch(:id)
|
|
70
|
+
rescue ::ROM::TupleCountMismatchError
|
|
71
|
+
raise EventNotFound.new(specification_event_id)
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def find_event_id_globally(specification_event_id)
|
|
75
|
+
events.by_event_id(specification_event_id).one!.fetch(:id)
|
|
76
|
+
rescue ::ROM::TupleCountMismatchError
|
|
77
|
+
raise EventNotFound.new(specification_event_id)
|
|
78
|
+
end
|
|
79
|
+
|
|
68
80
|
def read_scope(specification)
|
|
69
81
|
direction = specification.forward? ? :forward : :backward
|
|
70
82
|
|
|
@@ -73,20 +85,14 @@ module RubyEventStore
|
|
|
73
85
|
end
|
|
74
86
|
|
|
75
87
|
if specification.stream.global?
|
|
76
|
-
offset_entry_id =
|
|
77
|
-
stop_entry_id =
|
|
88
|
+
offset_entry_id = find_event_id_globally(specification.start) if specification.start
|
|
89
|
+
stop_entry_id = find_event_id_globally(specification.stop) if specification.stop
|
|
78
90
|
|
|
79
91
|
query = events.ordered(direction, offset_entry_id, stop_entry_id, specification.time_sort_by)
|
|
80
92
|
query = query.map_with(:event_to_serialized_record, auto_struct: false)
|
|
81
93
|
else
|
|
82
|
-
offset_entry_id =
|
|
83
|
-
|
|
84
|
-
.by_stream_and_event_id(specification.stream, specification.start)
|
|
85
|
-
.fetch(:id) if specification.start
|
|
86
|
-
stop_entry_id =
|
|
87
|
-
stream_entries
|
|
88
|
-
.by_stream_and_event_id(specification.stream, specification.stop)
|
|
89
|
-
.fetch(:id) if specification.stop
|
|
94
|
+
offset_entry_id = find_event_id_in_stream(specification.start, specification.stream) if specification.start
|
|
95
|
+
stop_entry_id = find_event_id_in_stream(specification.stop, specification.stream) if specification.stop
|
|
90
96
|
|
|
91
97
|
query =
|
|
92
98
|
stream_entries.ordered(
|
|
@@ -94,7 +100,7 @@ module RubyEventStore
|
|
|
94
100
|
specification.stream,
|
|
95
101
|
offset_entry_id,
|
|
96
102
|
stop_entry_id,
|
|
97
|
-
specification.time_sort_by
|
|
103
|
+
specification.time_sort_by,
|
|
98
104
|
)
|
|
99
105
|
query = query.combine(:event)
|
|
100
106
|
query = query.map_with(:stream_entry_to_serialized_record, auto_struct: false)
|
|
@@ -102,10 +108,18 @@ module RubyEventStore
|
|
|
102
108
|
|
|
103
109
|
query = query.by_event_id(specification.with_ids) if specification.with_ids
|
|
104
110
|
query = query.by_event_type(specification.with_types) if specification.with_types?
|
|
105
|
-
query = query.older_than(specification.older_than) if specification.older_than
|
|
106
|
-
query =
|
|
107
|
-
|
|
108
|
-
|
|
111
|
+
query = query.older_than(specification.older_than, specification.time_sort_by) if specification.older_than
|
|
112
|
+
query =
|
|
113
|
+
query.older_than_or_equal(
|
|
114
|
+
specification.older_than_or_equal,
|
|
115
|
+
specification.time_sort_by,
|
|
116
|
+
) if specification.older_than_or_equal
|
|
117
|
+
query = query.newer_than(specification.newer_than, specification.time_sort_by) if specification.newer_than
|
|
118
|
+
query =
|
|
119
|
+
query.newer_than_or_equal(
|
|
120
|
+
specification.newer_than_or_equal,
|
|
121
|
+
specification.time_sort_by,
|
|
122
|
+
) if specification.newer_than_or_equal
|
|
109
123
|
query
|
|
110
124
|
end
|
|
111
125
|
|
|
@@ -14,7 +14,7 @@ module RubyEventStore
|
|
|
14
14
|
tuples << {
|
|
15
15
|
stream: stream.name,
|
|
16
16
|
position: resolved_version && resolved_version + index + POSITION_SHIFT,
|
|
17
|
-
event_id: event_id
|
|
17
|
+
event_id: event_id,
|
|
18
18
|
}
|
|
19
19
|
end
|
|
20
20
|
end
|
|
@@ -29,7 +29,7 @@ module RubyEventStore
|
|
|
29
29
|
def resolve_version(stream, expected_version)
|
|
30
30
|
expected_version.resolve_for(
|
|
31
31
|
stream,
|
|
32
|
-
lambda { |_stream| (stream_entries.max_position(stream) || {})[:position] }
|
|
32
|
+
lambda { |_stream| (stream_entries.max_position(stream) || {})[:position] },
|
|
33
33
|
)
|
|
34
34
|
end
|
|
35
35
|
|
metadata
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: ruby_event_store-rom
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 2.
|
|
4
|
+
version: 2.3.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Joel Van Horn
|
|
8
|
-
autorequire:
|
|
9
8
|
bindir: bin
|
|
10
9
|
cert_chain: []
|
|
11
|
-
date:
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
12
11
|
dependencies:
|
|
13
12
|
- !ruby/object:Gem::Dependency
|
|
14
13
|
name: dry-container
|
|
@@ -117,7 +116,7 @@ dependencies:
|
|
|
117
116
|
version: 2.0.0
|
|
118
117
|
- - "<"
|
|
119
118
|
- !ruby/object:Gem::Version
|
|
120
|
-
version:
|
|
119
|
+
version: 4.0.0
|
|
121
120
|
type: :runtime
|
|
122
121
|
prerelease: false
|
|
123
122
|
version_requirements: !ruby/object:Gem::Requirement
|
|
@@ -127,7 +126,7 @@ dependencies:
|
|
|
127
126
|
version: 2.0.0
|
|
128
127
|
- - "<"
|
|
129
128
|
- !ruby/object:Gem::Version
|
|
130
|
-
version:
|
|
129
|
+
version: 4.0.0
|
|
131
130
|
description: Implementation of events repository based on ROM for Ruby Event Store
|
|
132
131
|
email: joel@joelvanhorn.com
|
|
133
132
|
executables: []
|
|
@@ -163,7 +162,6 @@ metadata:
|
|
|
163
162
|
source_code_uri: https://github.com/RailsEventStore/rails_event_store
|
|
164
163
|
bug_tracker_uri: https://github.com/RailsEventStore/rails_event_store/issues
|
|
165
164
|
rubygems_mfa_required: 'true'
|
|
166
|
-
post_install_message:
|
|
167
165
|
rdoc_options: []
|
|
168
166
|
require_paths:
|
|
169
167
|
- lib
|
|
@@ -171,15 +169,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
171
169
|
requirements:
|
|
172
170
|
- - ">="
|
|
173
171
|
- !ruby/object:Gem::Version
|
|
174
|
-
version: '2.
|
|
172
|
+
version: '2.7'
|
|
175
173
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
176
174
|
requirements:
|
|
177
175
|
- - ">="
|
|
178
176
|
- !ruby/object:Gem::Version
|
|
179
177
|
version: '0'
|
|
180
178
|
requirements: []
|
|
181
|
-
rubygems_version: 3.
|
|
182
|
-
signing_key:
|
|
179
|
+
rubygems_version: 3.7.1
|
|
183
180
|
specification_version: 4
|
|
184
181
|
summary: ROM events repository for Ruby Event Store
|
|
185
182
|
test_files: []
|