ruby_event_store 2.9.0 → 2.9.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
  SHA256:
3
- metadata.gz: fdf55a1535ea6531b1953ba7413455903257db368dba2bc369783cd90325a31f
4
- data.tar.gz: e7b071bbe5d4a389e47751af5d272a8dd9499af3c30c111b1dcba6ef8223e125
3
+ metadata.gz: 034aa1fb571c22b4e87df0161a00192535fdf8d6637df0e3db2fa9dc14c928d6
4
+ data.tar.gz: bbb8846d15f41eadf5e0c4cb3d63697ed80c536cfbd2c921453038ec40d0b3f9
5
5
  SHA512:
6
- metadata.gz: 5c95bb40dfeb3a8261970077ce5c6ac9e840d3eefeb56f0994b5aa91eb7c764e46f23d99281e33dc4f221a4cc74a504c83b6693230dcac16803e0e1678d86e7d
7
- data.tar.gz: a617e996ad6b0f72eb7d6cd7bfae02b2ad9151b001de72e71f2e03c28eed205be9abb35d633242487765d7b20e00bb37dc077475376ad89b8c0cf55662529491
6
+ metadata.gz: 5deb5169c06c20dfb077a0972a262fbf43fb1bf1e27257dd756a22d6f42eb34d1b486f34cebf7d55579bddb271b729ccd5e377d9f30ca5ed0abe814bba046ea5
7
+ data.tar.gz: 5188078974d0eb3d2311d00de74e69e5756e5d27b9afd7d1dc0cbbdc7b164fb26e6c27f52025215e2cd4978dc11e9eaa41f92f70502bd5516439a2205d8166b9
@@ -5,7 +5,7 @@ require "concurrent"
5
5
  module RubyEventStore
6
6
  class Client
7
7
  def initialize(
8
- repository:,
8
+ repository: InMemoryRepository.new,
9
9
  mapper: Mappers::Default.new,
10
10
  subscriptions: Subscriptions.new,
11
11
  dispatcher: Dispatcher.new,
@@ -153,19 +153,27 @@ module RubyEventStore
153
153
  serialized_records = serialized_records.drop(index_of(serialized_records, spec.start) + 1) if spec.start
154
154
  serialized_records = serialized_records.take(index_of(serialized_records, spec.stop)) if spec.stop
155
155
  serialized_records = serialized_records.take(spec.limit) if spec.limit?
156
- serialized_records = serialized_records.select { |sr| Time.iso8601(sr.timestamp) < spec.older_than } if spec
156
+ serialized_records = serialized_records.select { |sr| Time.iso8601(time_comparison_field(spec, sr)) < spec.older_than } if spec
157
157
  .older_than
158
158
  serialized_records =
159
- serialized_records.select { |sr| Time.iso8601(sr.timestamp) <= spec.older_than_or_equal } if spec
159
+ serialized_records.select { |sr| Time.iso8601(time_comparison_field(spec, sr)) <= spec.older_than_or_equal } if spec
160
160
  .older_than_or_equal
161
- serialized_records = serialized_records.select { |sr| Time.iso8601(sr.timestamp) > spec.newer_than } if spec
161
+ serialized_records = serialized_records.select { |sr| Time.iso8601(time_comparison_field(spec, sr)) > spec.newer_than } if spec
162
162
  .newer_than
163
163
  serialized_records =
164
- serialized_records.select { |sr| Time.iso8601(sr.timestamp) >= spec.newer_than_or_equal } if spec
164
+ serialized_records.select { |sr| Time.iso8601(time_comparison_field(spec, sr)) >= spec.newer_than_or_equal } if spec
165
165
  .newer_than_or_equal
166
166
  serialized_records
167
167
  end
168
168
 
169
+ def time_comparison_field(spec, sr)
170
+ if spec.time_sort_by_as_of?
171
+ sr.valid_at
172
+ else
173
+ sr.timestamp
174
+ end
175
+ end
176
+
169
177
  def read_event(event_id)
170
178
  storage.fetch(event_id) { raise EventNotFound.new(event_id) }
171
179
  end
@@ -6,7 +6,8 @@ module RubyEventStore
6
6
  def initialize(key_repository, serializer: Serializers::YAML, forgotten_data: ForgottenData.new)
7
7
  super(
8
8
  Pipeline.new(
9
- Transformation::Encryption.new(key_repository, serializer: serializer, forgotten_data: forgotten_data)
9
+ Transformation::Encryption.new(key_repository, serializer: serializer, forgotten_data: forgotten_data),
10
+ Transformation::SymbolizeMetadataKeys.new
10
11
  )
11
12
  )
12
13
  end
@@ -8,9 +8,9 @@ module RubyEventStore
8
8
  @instrumentation = instrumentation
9
9
  end
10
10
 
11
- def event_to_record(domain_event)
12
- instrumentation.instrument("serialize.mapper.rails_event_store", domain_event: domain_event) do
13
- mapper.event_to_record(domain_event)
11
+ def event_to_record(event)
12
+ instrumentation.instrument("serialize.mapper.rails_event_store", domain_event: event) do
13
+ mapper.event_to_record(event)
14
14
  end
15
15
  end
16
16
 
@@ -7,8 +7,8 @@ module RubyEventStore
7
7
  @transformations = [to_domain_event, transformations].flatten.freeze
8
8
  end
9
9
 
10
- def dump(domain_event)
11
- transformations.reduce(domain_event) { |item, transform| transform.dump(item) }
10
+ def dump(event)
11
+ transformations.reduce(event) { |item, transform| transform.dump(item) }
12
12
  end
13
13
 
14
14
  def load(record)
@@ -7,8 +7,8 @@ module RubyEventStore
7
7
  @pipeline = pipeline
8
8
  end
9
9
 
10
- def event_to_record(domain_event)
11
- pipeline.dump(domain_event)
10
+ def event_to_record(event)
11
+ pipeline.dump(event)
12
12
  end
13
13
 
14
14
  def record_to_event(record)
@@ -4,15 +4,15 @@ module RubyEventStore
4
4
  module Mappers
5
5
  module Transformation
6
6
  class DomainEvent
7
- def dump(domain_event)
8
- metadata = domain_event.metadata.dup.to_h
7
+ def dump(event)
8
+ metadata = event.metadata.dup.to_h
9
9
  timestamp = metadata.delete(:timestamp)
10
10
  valid_at = metadata.delete(:valid_at)
11
11
  Record.new(
12
- event_id: domain_event.event_id,
12
+ event_id: event.event_id,
13
13
  metadata: metadata,
14
- data: domain_event.data,
15
- event_type: domain_event.event_type,
14
+ data: event.data,
15
+ event_type: event.event_type,
16
16
  timestamp: timestamp,
17
17
  valid_at: valid_at
18
18
  )
@@ -33,7 +33,7 @@ end
33
33
  module RubyEventStore
34
34
  ::RSpec.shared_examples :event_repository do |mk_repository, helper|
35
35
  let(:repository) { mk_repository.call }
36
- let(:specification) { Specification.new(SpecificationReader.new(repository, Mappers::NullMapper.new)) }
36
+ let(:specification) { Specification.new(SpecificationReader.new(repository, Mappers::Default.new)) }
37
37
  let(:global_stream) { Stream.new(GLOBAL_STREAM) }
38
38
  let(:stream) { Stream.new(SecureRandom.uuid) }
39
39
  let(:stream_flow) { Stream.new("flow") }
@@ -968,6 +968,22 @@ module RubyEventStore
968
968
  expect(batches[1]).to eq(events[100..198])
969
969
  end
970
970
 
971
+ specify do
972
+ events = Array.new(200) { RubyEventStore::SRecord.new }
973
+ repository.append_to_stream(
974
+ events,
975
+ RubyEventStore::Stream.new(RubyEventStore::GLOBAL_STREAM),
976
+ RubyEventStore::ExpectedVersion.any
977
+ )
978
+
979
+ batches = repository.read(specification.as_at.forward.limit(101).in_batches.result).to_a
980
+ expect(batches.size).to eq(2)
981
+ expect(batches[0].size).to eq(100)
982
+ expect(batches[1].size).to eq(1)
983
+ expect(batches[0]).to eq(events[0..99])
984
+ expect(batches[1]).to eq([events[100]])
985
+ end
986
+
971
987
  specify do
972
988
  events = Array.new(200) { SRecord.new }
973
989
  repository.append_to_stream(events, Stream.new(GLOBAL_STREAM), ExpectedVersion.any)
@@ -1416,6 +1432,148 @@ module RubyEventStore
1416
1432
  )
1417
1433
  expect(repository.read(specification.result).count).to eq(0)
1418
1434
  end
1435
+
1436
+ specify "read in batches backward" do
1437
+ events = Array.new(200) { RubyEventStore::SRecord.new }
1438
+ repository.append_to_stream(
1439
+ events,
1440
+ RubyEventStore::Stream.new(RubyEventStore::GLOBAL_STREAM),
1441
+ RubyEventStore::ExpectedVersion.any
1442
+ )
1443
+
1444
+ batches = repository.read(specification.backward.limit(101).in_batches.result).to_a
1445
+ expect(batches.size).to eq(2)
1446
+ expect(batches[0].size).to eq(100)
1447
+ expect(batches[1].size).to eq(1)
1448
+ expect(batches[0]).to eq(events[100..-1].reverse)
1449
+ expect(batches[1]).to eq([events[99]])
1450
+ end
1451
+
1452
+ specify "read in batches forward" do
1453
+ events = Array.new(200) { RubyEventStore::SRecord.new }
1454
+ repository.append_to_stream(
1455
+ events,
1456
+ RubyEventStore::Stream.new(RubyEventStore::GLOBAL_STREAM),
1457
+ RubyEventStore::ExpectedVersion.any
1458
+ )
1459
+
1460
+ batches = repository.read(specification.forward.limit(101).in_batches.result).to_a
1461
+ expect(batches.size).to eq(2)
1462
+ expect(batches[0].size).to eq(100)
1463
+ expect(batches[1].size).to eq(1)
1464
+ expect(batches[0]).to eq(events[0..99])
1465
+ expect(batches[1]).to eq([events[100]])
1466
+ end
1467
+
1468
+ specify "read in batches forward from named stream" do
1469
+ all_events = Array.new(400) { RubyEventStore::SRecord.new }
1470
+ all_events.each_slice(2) do |(first, second)|
1471
+ repository.append_to_stream(
1472
+ [first],
1473
+ RubyEventStore::Stream.new("bazinga"),
1474
+ RubyEventStore::ExpectedVersion.any
1475
+ )
1476
+ repository.append_to_stream(
1477
+ [second],
1478
+ RubyEventStore::Stream.new(RubyEventStore::GLOBAL_STREAM),
1479
+ RubyEventStore::ExpectedVersion.any
1480
+ )
1481
+ end
1482
+ stream_events =
1483
+ all_events.each_with_index.select { |event, idx| event if idx % 2 == 0 }.map { |event, idx| event }
1484
+ batches = repository.read(specification.stream("bazinga").forward.limit(101).in_batches.result).to_a
1485
+ expect(batches.size).to eq(2)
1486
+ expect(batches[0].size).to eq(100)
1487
+ expect(batches[1].size).to eq(1)
1488
+ expect(batches[0]).to eq(stream_events[0..99])
1489
+ expect(batches[1]).to eq([stream_events[100]])
1490
+ end
1491
+
1492
+ specify "global stream order" do
1493
+ repository.append_to_stream(
1494
+ records = [
1495
+ RubyEventStore::SRecord.new(timestamp: with_precision(Time.new(2023, 1, 1, 12, 29, 0))),
1496
+ RubyEventStore::SRecord.new(timestamp: with_precision(Time.new(2023, 1, 1, 12, 28, 0))),
1497
+ RubyEventStore::SRecord.new(timestamp: with_precision(Time.new(2023, 1, 1, 12, 27, 0))),
1498
+ RubyEventStore::SRecord.new(timestamp: with_precision(Time.new(2023, 1, 1, 12, 26, 0)), valid_at: with_precision(Time.new(2023, 1, 1, 12, 30, 0))),
1499
+ ],
1500
+ RubyEventStore::Stream.new(RubyEventStore::GLOBAL_STREAM),
1501
+ RubyEventStore::ExpectedVersion.any
1502
+ )
1503
+
1504
+ expect(repository.read(specification.result).to_a).to eq([records[0], records[1], records[2], records[3]])
1505
+ expect(repository.read(specification.as_at.result).to_a).to eq([records[3], records[2], records[1], records[0]])
1506
+ expect(repository.read(specification.as_of.result).to_a).to eq([records[2], records[1], records[0], records[3]])
1507
+ end
1508
+
1509
+ specify "named stream order" do
1510
+ repository.append_to_stream(
1511
+ records = [
1512
+ RubyEventStore::SRecord.new(timestamp: with_precision(Time.new(2023, 1, 1, 12, 29, 0))),
1513
+ RubyEventStore::SRecord.new(timestamp: with_precision(Time.new(2023, 1, 1, 12, 28, 0))),
1514
+ RubyEventStore::SRecord.new(timestamp: with_precision(Time.new(2023, 1, 1, 12, 27, 0))),
1515
+ RubyEventStore::SRecord.new(timestamp: with_precision(Time.new(2023, 1, 1, 12, 26, 0)), valid_at: with_precision(Time.new(2023, 1, 1, 12, 30, 0))),
1516
+ ],
1517
+ RubyEventStore::Stream.new("stream"),
1518
+ RubyEventStore::ExpectedVersion.any
1519
+ )
1520
+
1521
+ expect(repository.read(specification.stream("stream").result).to_a).to eq([records[0], records[1], records[2], records[3]])
1522
+ expect(repository.read(specification.stream("stream").as_at.result).to_a).to eq([records[3], records[2], records[1], records[0]])
1523
+ expect(repository.read(specification.stream("stream").as_of.result).to_a).to eq([records[2], records[1], records[0], records[3]])
1524
+ end
1525
+
1526
+ specify "reading last event sorted by valid_at" do
1527
+ repository.append_to_stream(
1528
+ records = [
1529
+ RubyEventStore::SRecord.new(timestamp: with_precision(Time.new(2023, 1, 1, 12, 29, 0))),
1530
+ RubyEventStore::SRecord.new(timestamp: with_precision(Time.new(2023, 1, 1, 12, 28, 0))),
1531
+ RubyEventStore::SRecord.new(timestamp: with_precision(Time.new(2023, 1, 1, 12, 27, 0))),
1532
+ RubyEventStore::SRecord.new(timestamp: with_precision(Time.new(2023, 1, 1, 12, 26, 0)), valid_at: with_precision(Time.new(2023, 1, 1, 12, 30, 0))),
1533
+ ],
1534
+ RubyEventStore::Stream.new("stream"),
1535
+ RubyEventStore::ExpectedVersion.any
1536
+ )
1537
+
1538
+ expect(repository.read(specification.stream("stream").as_of.read_last.result)).to eq(records[3])
1539
+ end
1540
+
1541
+ specify "reading last event sorted by valid_at from global stream" do
1542
+ repository.append_to_stream(
1543
+ records = [
1544
+ SRecord.new(timestamp: with_precision(Time.new(2023, 1, 1, 12, 29, 0))),
1545
+ SRecord.new(timestamp: with_precision(Time.new(2023, 1, 1, 12, 28, 0))),
1546
+ SRecord.new(timestamp: with_precision(Time.new(2023, 1, 1, 12, 27, 0))),
1547
+ SRecord.new(timestamp: with_precision(Time.new(2023, 1, 1, 12, 26, 0)), valid_at: with_precision(Time.new(2023, 1, 1, 12, 30, 0))),
1548
+ ],
1549
+ Stream.new(GLOBAL_STREAM),
1550
+ ExpectedVersion.any
1551
+ )
1552
+
1553
+ expect(repository.read(specification.as_of.read_last.result)).to eq(records[3])
1554
+ end
1555
+
1556
+ specify "filter time by older than" do
1557
+ repository.append_to_stream(
1558
+ records = [
1559
+ SRecord.new(timestamp: with_precision(Time.utc(2023, 1, 1, 12, 29))),
1560
+ SRecord.new(timestamp: with_precision(Time.utc(2023, 1, 1, 12, 28))),
1561
+ SRecord.new(timestamp: with_precision(Time.utc(2023, 1, 1, 12, 27))),
1562
+ SRecord.new(timestamp: with_precision(Time.utc(2023, 1, 1, 12, 26)), valid_at: with_precision(Time.utc(2023, 1, 1, 12, 30))),
1563
+ ],
1564
+ Stream.new("stream"),
1565
+ ExpectedVersion.any
1566
+ )
1567
+
1568
+ expect(repository.read(specification.older_than(Time.utc(2023,1,1,12,28,1)).stream("stream").as_at.result).to_a).to eq([records[3], records[2], records[1]])
1569
+ expect(repository.read(specification.older_than(Time.utc(2023,1,1,12,28,1)).stream("stream").as_of.result).to_a).to eq([records[2], records[1]])
1570
+ end
1571
+
1572
+ private
1573
+
1574
+ def with_precision(time)
1575
+ time.round(TIMESTAMP_PRECISION)
1576
+ end
1419
1577
  end
1420
1578
 
1421
1579
  ::RSpec::Matchers.define :eq_ids do |expected_ids|
@@ -1,17 +1,17 @@
1
1
  module RubyEventStore
2
- ::RSpec.shared_examples :mapper do |mapper, domain_event|
2
+ ::RSpec.shared_examples :mapper do |mapper, event|
3
3
  specify "event_to_record returns instance of Record" do
4
- record = mapper.event_to_record(domain_event)
4
+ record = mapper.event_to_record(event)
5
5
 
6
6
  expect(record).to be_kind_of(Record)
7
- expect(record.event_id).to eq(domain_event.event_id)
8
- expect(record.event_type).to eq(domain_event.event_type)
7
+ expect(record.event_id).to eq(event.event_id)
8
+ expect(record.event_type).to eq(event.event_type)
9
9
  end
10
10
 
11
11
  specify "serialize and deserialize gives equal event" do
12
- record = mapper.event_to_record(domain_event)
12
+ record = mapper.event_to_record(event)
13
13
 
14
- expect(mapper.record_to_event(record)).to eq(domain_event)
14
+ expect(mapper.record_to_event(record)).to eq(event)
15
15
  end
16
16
  end
17
17
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module RubyEventStore
4
- VERSION = "2.9.0"
4
+ VERSION = "2.9.1"
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruby_event_store
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.9.0
4
+ version: 2.9.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Arkency
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-01-24 00:00:00.000000000 Z
11
+ date: 2023-02-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: concurrent-ruby
@@ -118,7 +118,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
118
118
  - !ruby/object:Gem::Version
119
119
  version: '0'
120
120
  requirements: []
121
- rubygems_version: 3.3.26
121
+ rubygems_version: 3.3.7
122
122
  signing_key:
123
123
  specification_version: 4
124
124
  summary: Implementation of an event store in Ruby