ruby_event_store-rom 2.0.0 → 2.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/README.md +0 -1
- data/lib/ruby_event_store/rom/changesets/create_events.rb +2 -2
- data/lib/ruby_event_store/rom/changesets/create_stream_entries.rb +2 -6
- data/lib/ruby_event_store/rom/changesets/update_events.rb +9 -8
- data/lib/ruby_event_store/rom/event_repository.rb +22 -20
- data/lib/ruby_event_store/rom/index_violation_detector.rb +11 -15
- data/lib/ruby_event_store/rom/mappers/event_to_serialized_record.rb +7 -3
- data/lib/ruby_event_store/rom/mappers/stream_entry_to_serialized_record.rb +7 -3
- data/lib/ruby_event_store/rom/rake_task.rb +1 -1
- data/lib/ruby_event_store/rom/relations/events.rb +31 -18
- data/lib/ruby_event_store/rom/relations/stream_entries.rb +37 -20
- data/lib/ruby_event_store/rom/repositories/events.rb +36 -17
- data/lib/ruby_event_store/rom/repositories/stream_entries.rb +8 -3
- data/lib/ruby_event_store/rom/tasks/migration_tasks.rake +5 -5
- data/lib/ruby_event_store/rom/types.rb +16 -14
- data/lib/ruby_event_store/rom/unit_of_work.rb +5 -6
- data/lib/ruby_event_store/rom/version.rb +1 -1
- data/lib/ruby_event_store/rom.rb +2 -4
- metadata +5 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0346bda57c2f37b5dd9f545f51d980fef10af52630613aa4741f48aa57d3e8eb
|
4
|
+
data.tar.gz: 2e451dd750e028ee9f8a3182e65721c7e3c569a1ac283f9e25cb66e92ac89fac
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b4f057692be3234140fdc0102cc66af4280e1a9b83ecaff362d6a18c644fd7df5ed089dd85e3f62d10ee871d5c41fc1a1660cc96aff08d81f728554c65563070
|
7
|
+
data.tar.gz: 3eda5e842ca678da3039b04458f910021ba5639c286c8d5c0eee9c4ccfa2a10d4da3f2c4d534e7e6e65f3dd94d5e26385353b63eba36953b4bcf507e18af9785
|
data/README.md
CHANGED
@@ -7,4 +7,3 @@ 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
|
-
|
@@ -9,8 +9,8 @@ module RubyEventStore
|
|
9
9
|
map(&:to_h)
|
10
10
|
map do
|
11
11
|
rename_keys timestamp: :created_at
|
12
|
-
map_value
|
13
|
-
map_value
|
12
|
+
map_value :created_at, ->(time) { Time.iso8601(time).localtime }
|
13
|
+
map_value :valid_at, ->(time) { Time.iso8601(time).localtime }
|
14
14
|
accept_keys %i[event_id data metadata event_type created_at valid_at]
|
15
15
|
end
|
16
16
|
|
@@ -6,12 +6,8 @@ module RubyEventStore
|
|
6
6
|
class CreateStreamEntries < ::ROM::Changeset::Create
|
7
7
|
relation :stream_entries
|
8
8
|
|
9
|
-
map
|
10
|
-
|
11
|
-
end
|
12
|
-
map do
|
13
|
-
map_value :created_at, ->(datetime) { datetime.to_time.localtime }
|
14
|
-
end
|
9
|
+
map { |tuple| Hash(created_at: RubyEventStore::ROM::Types::DateTime.call(nil)).merge(tuple) }
|
10
|
+
map { map_value :created_at, ->(datetime) { datetime.to_time.localtime } }
|
15
11
|
end
|
16
12
|
end
|
17
13
|
end
|
@@ -9,8 +9,8 @@ module RubyEventStore
|
|
9
9
|
map(&:to_h)
|
10
10
|
map do
|
11
11
|
rename_keys timestamp: :created_at
|
12
|
-
map_value
|
13
|
-
map_value
|
12
|
+
map_value :created_at, ->(time) { Time.iso8601(time).localtime }
|
13
|
+
map_value :valid_at, ->(time) { Time.iso8601(time).localtime }
|
14
14
|
accept_keys %i[event_id data metadata event_type created_at valid_at]
|
15
15
|
end
|
16
16
|
|
@@ -31,12 +31,13 @@ module RubyEventStore
|
|
31
31
|
end
|
32
32
|
|
33
33
|
def commit_insert_conflict_update
|
34
|
-
relation
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
34
|
+
relation
|
35
|
+
.dataset
|
36
|
+
.insert_conflict(
|
37
|
+
target: :event_id,
|
38
|
+
update: UPSERT_COLUMNS.each_with_object({}) { |column, memo| memo[column] = Sequel[:excluded][column] }
|
39
|
+
)
|
40
|
+
.multi_insert(to_a)
|
40
41
|
end
|
41
42
|
end
|
42
43
|
end
|
@@ -4,24 +4,25 @@ module RubyEventStore
|
|
4
4
|
module ROM
|
5
5
|
class EventRepository
|
6
6
|
def initialize(rom:, serializer:)
|
7
|
-
@serializer
|
8
|
-
@events
|
7
|
+
@serializer = serializer
|
8
|
+
@events = Repositories::Events.new(rom)
|
9
9
|
@stream_entries = Repositories::StreamEntries.new(rom)
|
10
|
-
@unit_of_work
|
10
|
+
@unit_of_work = UnitOfWork.new(rom.gateways.fetch(:default))
|
11
11
|
end
|
12
12
|
|
13
13
|
def append_to_stream(records, stream, expected_version)
|
14
14
|
serialized_records = records.map { |record| record.serialize(@serializer) }
|
15
|
-
event_ids
|
15
|
+
event_ids = records.map(&:event_id)
|
16
16
|
|
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
|
-
|
20
|
+
changesets <<
|
21
|
+
@stream_entries.create_changeset(
|
22
|
+
event_ids,
|
23
|
+
stream,
|
24
|
+
@stream_entries.resolve_version(stream, expected_version)
|
25
|
+
)
|
25
26
|
end
|
26
27
|
end
|
27
28
|
|
@@ -33,11 +34,12 @@ module RubyEventStore
|
|
33
34
|
|
34
35
|
handle_unique_violation do
|
35
36
|
@unit_of_work.call do |changesets|
|
36
|
-
changesets <<
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
37
|
+
changesets <<
|
38
|
+
@stream_entries.create_changeset(
|
39
|
+
event_ids,
|
40
|
+
stream,
|
41
|
+
@stream_entries.resolve_version(stream, expected_version)
|
42
|
+
)
|
41
43
|
end
|
42
44
|
end
|
43
45
|
|
@@ -52,6 +54,10 @@ module RubyEventStore
|
|
52
54
|
@events.global_position(event_id)
|
53
55
|
end
|
54
56
|
|
57
|
+
def event_in_stream?(event_id, stream)
|
58
|
+
@stream_entries.event_in_stream?(event_id, stream)
|
59
|
+
end
|
60
|
+
|
55
61
|
def delete_stream(stream)
|
56
62
|
@stream_entries.delete(stream)
|
57
63
|
end
|
@@ -85,17 +91,13 @@ module RubyEventStore
|
|
85
91
|
end
|
86
92
|
|
87
93
|
def streams_of(event_id)
|
88
|
-
@stream_entries
|
89
|
-
.streams_of(event_id)
|
90
|
-
.map { |name| Stream.new(name) }
|
94
|
+
@stream_entries.streams_of(event_id).map { |name| Stream.new(name) }
|
91
95
|
end
|
92
96
|
|
93
97
|
private
|
94
98
|
|
95
99
|
def validate_event_ids(event_ids)
|
96
|
-
@events
|
97
|
-
.find_nonexistent_pks(event_ids)
|
98
|
-
.each { |id| raise EventNotFound, id }
|
100
|
+
@events.find_nonexistent_pks(event_ids).each { |id| raise EventNotFound, id }
|
99
101
|
end
|
100
102
|
|
101
103
|
def handle_unique_violation
|
@@ -3,26 +3,22 @@
|
|
3
3
|
module RubyEventStore
|
4
4
|
module ROM
|
5
5
|
class IndexViolationDetector
|
6
|
-
MYSQL5_PKEY_ERROR
|
7
|
-
MYSQL8_PKEY_ERROR
|
6
|
+
MYSQL5_PKEY_ERROR = "for key 'index_event_store_events_on_event_id'".freeze
|
7
|
+
MYSQL8_PKEY_ERROR = "for key 'event_store_events.index_event_store_events_on_event_id'".freeze
|
8
8
|
POSTGRES_PKEY_ERROR = "Key (event_id)".freeze
|
9
|
-
SQLITE3_PKEY_ERROR
|
9
|
+
SQLITE3_PKEY_ERROR = "event_store_events.event_id".freeze
|
10
10
|
|
11
|
-
MYSQL5_INDEX_ERROR
|
12
|
-
MYSQL8_INDEX_ERROR
|
11
|
+
MYSQL5_INDEX_ERROR = "for key 'index_event_store_events_in_streams_on_stream_and_event_id'".freeze
|
12
|
+
MYSQL8_INDEX_ERROR =
|
13
|
+
"for key 'event_store_events_in_streams.index_event_store_events_in_streams_on_stream_and_event_id'".freeze
|
13
14
|
POSTGRES_INDEX_ERROR = "Key (stream, event_id)".freeze
|
14
|
-
SQLITE3_INDEX_ERROR
|
15
|
+
SQLITE3_INDEX_ERROR = "event_store_events_in_streams.stream, event_store_events_in_streams.event_id".freeze
|
15
16
|
|
16
17
|
def detect(message)
|
17
|
-
message.include?(MYSQL5_PKEY_ERROR) ||
|
18
|
-
message.include?(
|
19
|
-
message.include?(
|
20
|
-
message.include?(
|
21
|
-
|
22
|
-
message.include?(MYSQL5_INDEX_ERROR) ||
|
23
|
-
message.include?(MYSQL8_INDEX_ERROR) ||
|
24
|
-
message.include?(POSTGRES_INDEX_ERROR) ||
|
25
|
-
message.include?(SQLITE3_INDEX_ERROR)
|
18
|
+
message.include?(MYSQL5_PKEY_ERROR) || message.include?(MYSQL8_PKEY_ERROR) ||
|
19
|
+
message.include?(POSTGRES_PKEY_ERROR) || message.include?(SQLITE3_PKEY_ERROR) ||
|
20
|
+
message.include?(MYSQL5_INDEX_ERROR) || message.include?(MYSQL8_INDEX_ERROR) ||
|
21
|
+
message.include?(POSTGRES_INDEX_ERROR) || message.include?(SQLITE3_INDEX_ERROR)
|
26
22
|
end
|
27
23
|
end
|
28
24
|
end
|
@@ -7,12 +7,16 @@ module RubyEventStore
|
|
7
7
|
relation :events
|
8
8
|
register_as :event_to_serialized_record
|
9
9
|
|
10
|
-
|
10
|
+
map do
|
11
11
|
map_value :created_at, ->(time) { time.iso8601(TIMESTAMP_PRECISION) }
|
12
|
-
map_value :valid_at,
|
12
|
+
map_value :valid_at, ->(time) { time.iso8601(TIMESTAMP_PRECISION) }
|
13
13
|
rename_keys created_at: :timestamp
|
14
14
|
accept_keys %i[event_id data metadata event_type timestamp valid_at]
|
15
|
-
|
15
|
+
create_serialized_record
|
16
|
+
end
|
17
|
+
|
18
|
+
def create_serialized_record(attributes)
|
19
|
+
RubyEventStore::SerializedRecord.new(**attributes)
|
16
20
|
end
|
17
21
|
end
|
18
22
|
end
|
@@ -7,13 +7,17 @@ module RubyEventStore
|
|
7
7
|
relation :stream_entries
|
8
8
|
register_as :stream_entry_to_serialized_record
|
9
9
|
|
10
|
-
|
10
|
+
map do
|
11
11
|
unwrap :event, %i[event_id data metadata event_type created_at valid_at]
|
12
12
|
map_value :created_at, ->(time) { time.iso8601(TIMESTAMP_PRECISION) }
|
13
|
-
map_value :valid_at,
|
13
|
+
map_value :valid_at, ->(time) { time.iso8601(TIMESTAMP_PRECISION) }
|
14
14
|
rename_keys created_at: :timestamp
|
15
15
|
accept_keys %i[event_id data metadata event_type timestamp valid_at]
|
16
|
-
|
16
|
+
create_serialized_record
|
17
|
+
end
|
18
|
+
|
19
|
+
def create_serialized_record(attributes)
|
20
|
+
RubyEventStore::SerializedRecord.new(**attributes)
|
17
21
|
end
|
18
22
|
end
|
19
23
|
end
|
@@ -6,18 +6,18 @@ module RubyEventStore
|
|
6
6
|
class Events < ::ROM::Relation[:sql]
|
7
7
|
schema(:event_store_events, as: :events, infer: true) do
|
8
8
|
attribute :event_id, ::ROM::Types::String
|
9
|
-
attribute :data,
|
10
|
-
|
11
|
-
|
12
|
-
|
9
|
+
attribute :data,
|
10
|
+
RubyEventStore::ROM::Types::RecordSerializer,
|
11
|
+
read: RubyEventStore::ROM::Types::RecordDeserializer
|
12
|
+
attribute :metadata,
|
13
|
+
RubyEventStore::ROM::Types::RecordSerializer,
|
14
|
+
read: RubyEventStore::ROM::Types::RecordDeserializer
|
13
15
|
attribute :created_at, RubyEventStore::ROM::Types::DateTime
|
14
16
|
attribute :valid_at, RubyEventStore::ROM::Types::DateTime
|
15
17
|
|
16
18
|
primary_key :event_id
|
17
19
|
end
|
18
20
|
|
19
|
-
alias take limit
|
20
|
-
|
21
21
|
def create_changeset(tuples)
|
22
22
|
events.changeset(Changesets::CreateEvents, tuples)
|
23
23
|
end
|
@@ -34,26 +34,39 @@ 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
|
-
DIRECTION_MAP = {
|
54
|
-
forward: %i[asc > <],
|
55
|
-
backward: %i[desc < >]
|
56
|
-
}.freeze
|
69
|
+
DIRECTION_MAP = { forward: %i[asc > <], backward: %i[desc < >] }.freeze
|
57
70
|
|
58
71
|
def ordered(direction, offset_entry_id = nil, stop_entry_id = nil, time_sort_by = nil)
|
59
72
|
order, operator_offset, operator_stop = DIRECTION_MAP[direction]
|
@@ -7,13 +7,9 @@ module RubyEventStore
|
|
7
7
|
schema(:event_store_events_in_streams, as: :stream_entries, infer: true) do
|
8
8
|
attribute :created_at, RubyEventStore::ROM::Types::DateTime
|
9
9
|
|
10
|
-
associations
|
11
|
-
belongs_to :events, as: :event, foreign_key: :event_id
|
12
|
-
end
|
10
|
+
associations { belongs_to :events, as: :event, foreign_key: :event_id }
|
13
11
|
end
|
14
12
|
|
15
|
-
alias take limit
|
16
|
-
|
17
13
|
def create_changeset(tuples)
|
18
14
|
changeset(ROM::Changesets::CreateStreamEntries, tuples)
|
19
15
|
end
|
@@ -27,7 +23,7 @@ module RubyEventStore
|
|
27
23
|
end
|
28
24
|
|
29
25
|
def by_event_type(types)
|
30
|
-
|
26
|
+
join_events.where(event_type: types)
|
31
27
|
end
|
32
28
|
|
33
29
|
def by_stream_and_event_id(stream, event_id)
|
@@ -38,33 +34,46 @@ module RubyEventStore
|
|
38
34
|
by_stream(stream).select(:position).order(Sequel.desc(:position)).first
|
39
35
|
end
|
40
36
|
|
41
|
-
def newer_than(time)
|
42
|
-
|
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
|
43
43
|
end
|
44
44
|
|
45
|
-
def newer_than_or_equal(time)
|
46
|
-
|
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
|
47
51
|
end
|
48
52
|
|
49
|
-
def older_than(time)
|
50
|
-
|
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
|
51
59
|
end
|
52
60
|
|
53
|
-
def older_than_or_equal(time)
|
54
|
-
|
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
|
55
67
|
end
|
56
68
|
|
57
|
-
DIRECTION_MAP = {
|
58
|
-
forward: %i[asc > <],
|
59
|
-
backward: %i[desc < >]
|
60
|
-
}.freeze
|
69
|
+
DIRECTION_MAP = { forward: %i[asc > <], backward: %i[desc < >] }.freeze
|
61
70
|
|
62
71
|
def ordered(direction, stream, offset_entry_id = nil, stop_entry_id = nil, time_sort_by = nil)
|
63
72
|
order, operator_offset, operator_stop = DIRECTION_MAP[direction]
|
64
73
|
|
65
74
|
raise ArgumentError, "Direction must be :forward or :backward" if order.nil?
|
66
75
|
|
67
|
-
event_order_columns
|
76
|
+
event_order_columns = []
|
68
77
|
stream_order_columns = %i[id]
|
69
78
|
|
70
79
|
case time_sort_by
|
@@ -81,7 +90,15 @@ module RubyEventStore
|
|
81
90
|
if event_order_columns.empty?
|
82
91
|
query.order { |r| stream_order_columns.map { |c| r[:stream_entries][c].public_send(order) } }
|
83
92
|
else
|
84
|
-
query.
|
93
|
+
query.join_events.order { |r| event_order_columns.map { |c| r.events[c].public_send(order) } }
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
def join_events
|
98
|
+
if dataset.opts[:join]&.map(&:table)&.include?(events.dataset.first_source_table)
|
99
|
+
self
|
100
|
+
else
|
101
|
+
join(:events)
|
85
102
|
end
|
86
103
|
end
|
87
104
|
end
|
@@ -53,7 +53,7 @@ module RubyEventStore
|
|
53
53
|
|
54
54
|
def count(specification)
|
55
55
|
query = read_scope(specification)
|
56
|
-
query = query.
|
56
|
+
query = query.limit(specification.limit) if specification.limit?
|
57
57
|
query.count
|
58
58
|
end
|
59
59
|
|
@@ -65,6 +65,20 @@ 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
|
70
|
+
.by_stream_and_event_id(specification_stream_name, specification_event_id)
|
71
|
+
.fetch(:id)
|
72
|
+
rescue ::ROM::TupleCountMismatchError
|
73
|
+
raise EventNotFound.new(specification_event_id)
|
74
|
+
end
|
75
|
+
|
76
|
+
def find_event_id_globally(specification_event_id)
|
77
|
+
events.by_event_id(specification_event_id).one!.fetch(:id)
|
78
|
+
rescue ::ROM::TupleCountMismatchError
|
79
|
+
raise EventNotFound.new(specification_event_id)
|
80
|
+
end
|
81
|
+
|
68
82
|
def read_scope(specification)
|
69
83
|
direction = specification.forward? ? :forward : :backward
|
70
84
|
|
@@ -73,35 +87,40 @@ module RubyEventStore
|
|
73
87
|
end
|
74
88
|
|
75
89
|
if specification.stream.global?
|
76
|
-
offset_entry_id =
|
77
|
-
stop_entry_id
|
90
|
+
offset_entry_id = find_event_id_globally(specification.start) if specification.start
|
91
|
+
stop_entry_id = find_event_id_globally(specification.stop) if specification.stop
|
78
92
|
|
79
93
|
query = events.ordered(direction, offset_entry_id, stop_entry_id, specification.time_sort_by)
|
80
94
|
query = query.map_with(:event_to_serialized_record, auto_struct: false)
|
81
95
|
else
|
82
|
-
offset_entry_id =
|
83
|
-
stop_entry_id
|
84
|
-
|
85
|
-
query =
|
96
|
+
offset_entry_id = find_event_id_in_stream(specification.start, specification.stream) if specification.start
|
97
|
+
stop_entry_id = find_event_id_in_stream(specification.stop, specification.stream) if specification.stop
|
98
|
+
|
99
|
+
query =
|
100
|
+
stream_entries.ordered(
|
101
|
+
direction,
|
102
|
+
specification.stream,
|
103
|
+
offset_entry_id,
|
104
|
+
stop_entry_id,
|
105
|
+
specification.time_sort_by
|
106
|
+
)
|
86
107
|
query = query.combine(:event)
|
87
108
|
query = query.map_with(:stream_entry_to_serialized_record, auto_struct: false)
|
88
109
|
end
|
89
110
|
|
90
|
-
query = query.by_event_id(specification.with_ids)
|
91
|
-
query = query.by_event_type(specification.with_types)
|
92
|
-
query = query.older_than(specification.older_than)
|
93
|
-
query = query.older_than_or_equal(specification.older_than_or_equal) if specification.older_than_or_equal
|
94
|
-
query = query.newer_than(specification.newer_than)
|
95
|
-
query = query.newer_than_or_equal(specification.newer_than_or_equal) if specification.newer_than_or_equal
|
111
|
+
query = query.by_event_id(specification.with_ids) if specification.with_ids
|
112
|
+
query = query.by_event_type(specification.with_types) if specification.with_types?
|
113
|
+
query = query.older_than(specification.older_than, specification.time_sort_by) if specification.older_than
|
114
|
+
query = query.older_than_or_equal(specification.older_than_or_equal, specification.time_sort_by) if specification.older_than_or_equal
|
115
|
+
query = query.newer_than(specification.newer_than, specification.time_sort_by) if specification.newer_than
|
116
|
+
query = query.newer_than_or_equal(specification.newer_than_or_equal, specification.time_sort_by) if specification.newer_than_or_equal
|
96
117
|
query
|
97
118
|
end
|
98
119
|
|
99
120
|
def query_builder(serializer, query, offset: nil, limit: nil)
|
100
121
|
query = query.offset(offset) if offset
|
101
|
-
query = query.
|
102
|
-
query
|
103
|
-
.to_a
|
104
|
-
.map { |serialized_record| serialized_record.deserialize(serializer) }
|
122
|
+
query = query.limit(limit) if limit
|
123
|
+
query.to_a.map { |serialized_record| serialized_record.deserialize(serializer) }
|
105
124
|
end
|
106
125
|
end
|
107
126
|
end
|
@@ -27,9 +27,10 @@ module RubyEventStore
|
|
27
27
|
end
|
28
28
|
|
29
29
|
def resolve_version(stream, expected_version)
|
30
|
-
expected_version.resolve_for(
|
31
|
-
|
32
|
-
|
30
|
+
expected_version.resolve_for(
|
31
|
+
stream,
|
32
|
+
lambda { |_stream| (stream_entries.max_position(stream) || {})[:position] }
|
33
|
+
)
|
33
34
|
end
|
34
35
|
|
35
36
|
def streams_of(event_id)
|
@@ -41,6 +42,10 @@ module RubyEventStore
|
|
41
42
|
raise EventNotFoundInStream if record.nil?
|
42
43
|
record.position
|
43
44
|
end
|
45
|
+
|
46
|
+
def event_in_stream?(event_id, stream)
|
47
|
+
stream_entries.by_stream(stream).by_event_id(event_id).exist?
|
48
|
+
end
|
44
49
|
end
|
45
50
|
end
|
46
51
|
end
|
@@ -7,7 +7,7 @@ MIGRATIONS_PATH = "db/migrate".freeze
|
|
7
7
|
desc "Setup ROM EventRespository environment"
|
8
8
|
task "db:setup" do
|
9
9
|
Dir.chdir(Dir.pwd)
|
10
|
-
ROM::SQL::RakeSupport.env = ::RubyEventStore::ROM.
|
10
|
+
ROM::SQL::RakeSupport.env = ::RubyEventStore::ROM.rom_container(:sql, ENV["DATABASE_URL"])
|
11
11
|
end
|
12
12
|
|
13
13
|
desc "Copy RubyEventStore SQL migrations to db/migrate"
|
@@ -15,19 +15,19 @@ task "db:migrations:copy" => "db:setup" do
|
|
15
15
|
# Optional data type for `data` and `metadata`
|
16
16
|
data_type = ENV["DATA_TYPE"]
|
17
17
|
|
18
|
-
Dir[File.join(File.dirname(__FILE__), "
|
18
|
+
Dir[File.join(File.dirname(__FILE__), "../../../../", MIGRATIONS_PATH, "/*.rb")].each do |input|
|
19
19
|
contents = File.read(input)
|
20
|
-
name
|
20
|
+
name = File.basename(input, ".*").sub(/\d+_/, "")
|
21
21
|
|
22
22
|
re_data_type = /(ENV.+?DATA_TYPE.+?\|\|=\s*)['"](jsonb?|text)['"]/
|
23
23
|
|
24
24
|
if data_type && contents =~ re_data_type
|
25
25
|
# Search/replace this string: ENV['DATA_TYPE'] ||= 'text'
|
26
26
|
contents = contents.sub(re_data_type, format('\1"%<data_type>s"', data_type: data_type))
|
27
|
-
name
|
27
|
+
name += "_with_#{data_type}"
|
28
28
|
end
|
29
29
|
|
30
|
-
output = ROM::SQL::RakeSupport.create_migration(name
|
30
|
+
output = ROM::SQL::RakeSupport.create_migration(name)
|
31
31
|
|
32
32
|
File.write output, contents
|
33
33
|
|
@@ -3,22 +3,24 @@
|
|
3
3
|
module RubyEventStore
|
4
4
|
module ROM
|
5
5
|
module Types
|
6
|
-
DateTime =
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
6
|
+
DateTime =
|
7
|
+
::ROM::Types::DateTime
|
8
|
+
.constructor do |value|
|
9
|
+
case value
|
10
|
+
when nil
|
11
|
+
Dry::Core::Constants::Undefined
|
12
|
+
when ::String
|
13
|
+
::DateTime.iso8601(value)
|
14
|
+
else
|
15
|
+
value
|
16
|
+
end
|
17
|
+
end
|
18
|
+
.default { ::DateTime.now.new_offset(0) }
|
18
19
|
|
19
20
|
# detects if the value is a Sequel::Postgres::JSONHash or Sequel::Postgres::JSONBHash
|
20
|
-
RecordDeserializer =
|
21
|
-
|
21
|
+
RecordDeserializer =
|
22
|
+
::ROM::Types::String.constructor { |v| v.class.name.upcase.include?("JSON") ? JSON.dump(v) : v }
|
23
|
+
RecordSerializer = ::ROM::Types::String
|
22
24
|
end
|
23
25
|
end
|
24
26
|
end
|
@@ -29,12 +29,11 @@ module RubyEventStore
|
|
29
29
|
# MySQL deadlocks or to allow Sequel to retry transactions
|
30
30
|
# when the :retry_on option is specified.
|
31
31
|
retry_on: Sequel::SerializationFailure,
|
32
|
-
before_retry:
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
end
|
32
|
+
before_retry:
|
33
|
+
lambda do |_num, ex|
|
34
|
+
env.logger.warn("RETRY TRANSACTION [#{self.class.name} => #{ex.class.name}] #{ex.message}")
|
35
|
+
end
|
36
|
+
) { changesets.each(&:commit) }
|
38
37
|
end
|
39
38
|
end
|
40
39
|
end
|
data/lib/ruby_event_store/rom.rb
CHANGED
@@ -24,15 +24,13 @@ module RubyEventStore
|
|
24
24
|
class << self
|
25
25
|
def setup(adapter_name, database_uri = ENV["DATABASE_URL"])
|
26
26
|
rom_container(adapter_name, database_uri) do |rom|
|
27
|
-
rom.register_mapper
|
28
|
-
rom.register_mapper
|
27
|
+
rom.register_mapper Mappers::StreamEntryToSerializedRecord
|
28
|
+
rom.register_mapper Mappers::EventToSerializedRecord
|
29
29
|
rom.register_relation Relations::Events
|
30
30
|
rom.register_relation Relations::StreamEntries
|
31
31
|
end
|
32
32
|
end
|
33
33
|
|
34
|
-
private
|
35
|
-
|
36
34
|
def rom_container(adapter_name, database_uri, &block)
|
37
35
|
if adapter_name.is_a?(::ROM::Configuration)
|
38
36
|
::ROM.container(adapter_name.tap(&block), &block)
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
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.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Joel Van Horn
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2023-09-04 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: dry-container
|
@@ -162,6 +162,7 @@ metadata:
|
|
162
162
|
changelog_uri: https://github.com/RailsEventStore/rails_event_store/blob/master/contrib/ruby_event_store-rom/CHANGELOG.md
|
163
163
|
source_code_uri: https://github.com/RailsEventStore/rails_event_store
|
164
164
|
bug_tracker_uri: https://github.com/RailsEventStore/rails_event_store/issues
|
165
|
+
rubygems_mfa_required: 'true'
|
165
166
|
post_install_message:
|
166
167
|
rdoc_options: []
|
167
168
|
require_paths:
|
@@ -170,14 +171,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
170
171
|
requirements:
|
171
172
|
- - ">="
|
172
173
|
- !ruby/object:Gem::Version
|
173
|
-
version: '2.
|
174
|
+
version: '2.7'
|
174
175
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
175
176
|
requirements:
|
176
177
|
- - ">="
|
177
178
|
- !ruby/object:Gem::Version
|
178
179
|
version: '0'
|
179
180
|
requirements: []
|
180
|
-
rubygems_version: 3.
|
181
|
+
rubygems_version: 3.4.17
|
181
182
|
signing_key:
|
182
183
|
specification_version: 4
|
183
184
|
summary: ROM events repository for Ruby Event Store
|