rails_event_store_active_record 2.1.0 → 2.4.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 +1 -1
 - data/lib/rails_event_store_active_record/batch_enumerator.rb +3 -4
 - data/lib/rails_event_store_active_record/event.rb +3 -3
 - data/lib/rails_event_store_active_record/event_repository.rb +61 -37
 - data/lib/rails_event_store_active_record/event_repository_reader.rb +83 -44
 - data/lib/rails_event_store_active_record/generators/migration_generator.rb +10 -8
 - data/lib/rails_event_store_active_record/generators/templates/create_event_store_events_template.rb +30 -26
 - data/lib/rails_event_store_active_record/index_violation_detector.rb +15 -19
 - data/lib/rails_event_store_active_record/pg_linearized_event_repository.rb +1 -8
 - data/lib/rails_event_store_active_record/version.rb +1 -1
 - data/lib/rails_event_store_active_record/with_abstract_base_class.rb +11 -11
 - data/lib/rails_event_store_active_record.rb +10 -10
 - metadata +9 -22
 
    
        checksums.yaml
    CHANGED
    
    | 
         @@ -1,7 +1,7 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            ---
         
     | 
| 
       2 
2 
     | 
    
         
             
            SHA256:
         
     | 
| 
       3 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       4 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 3 
     | 
    
         
            +
              metadata.gz: b146f907eef70a988c0949381dbf897a4f93bd7aa9e1ccf8346559c2656feb80
         
     | 
| 
      
 4 
     | 
    
         
            +
              data.tar.gz: 46b6f4ce8d62b7386d72a1219a375e012bd3d15b33b16fe552cb8adee9f4f6e4
         
     | 
| 
       5 
5 
     | 
    
         
             
            SHA512:
         
     | 
| 
       6 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       7 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 6 
     | 
    
         
            +
              metadata.gz: 0be237c7518c776a5ee19e8625f39966a20f255b0076839695957df0aa337c181bc7c85351afb2a1fbffdd6b0fd75fa50217482c30d1aa82437b242a32552e8d
         
     | 
| 
      
 7 
     | 
    
         
            +
              data.tar.gz: 32aa1160ba4de4081357319e25012330249b6e946d0e0b558452fe41e7a30aa25e70d65faf9897ba6b7afac841c6b2ea6011117a892a272179da58b38a96bbb4
         
     | 
    
        data/README.md
    CHANGED
    
    | 
         @@ -4,4 +4,4 @@ Persistent event repository implementation for RubyEventStore based on ActiveRec 
     | 
|
| 
       4 
4 
     | 
    
         | 
| 
       5 
5 
     | 
    
         
             
            Includes repository implementation with linearized writes to achieve log-like properties of streams on top of SQL database engine.
         
     | 
| 
       6 
6 
     | 
    
         | 
| 
       7 
     | 
    
         
            -
            Find out more at [https://railseventstore.org](https://railseventstore.org/)
         
     | 
| 
      
 7 
     | 
    
         
            +
            Find out more at [https://railseventstore.org](https://railseventstore.org/)
         
     | 
| 
         @@ -3,9 +3,9 @@ 
     | 
|
| 
       3 
3 
     | 
    
         
             
            module RailsEventStoreActiveRecord
         
     | 
| 
       4 
4 
     | 
    
         
             
              class BatchEnumerator
         
     | 
| 
       5 
5 
     | 
    
         
             
                def initialize(batch_size, total_limit, reader)
         
     | 
| 
       6 
     | 
    
         
            -
                  @batch_size 
     | 
| 
      
 6 
     | 
    
         
            +
                  @batch_size = batch_size
         
     | 
| 
       7 
7 
     | 
    
         
             
                  @total_limit = total_limit
         
     | 
| 
       8 
     | 
    
         
            -
                  @reader 
     | 
| 
      
 8 
     | 
    
         
            +
                  @reader = reader
         
     | 
| 
       9 
9 
     | 
    
         
             
                end
         
     | 
| 
       10 
10 
     | 
    
         | 
| 
       11 
11 
     | 
    
         
             
                def each
         
     | 
| 
         @@ -13,7 +13,7 @@ module RailsEventStoreActiveRecord 
     | 
|
| 
       13 
13 
     | 
    
         
             
                  offset_id = nil
         
     | 
| 
       14 
14 
     | 
    
         | 
| 
       15 
15 
     | 
    
         
             
                  0.step(total_limit - 1, batch_size) do |batch_offset|
         
     | 
| 
       16 
     | 
    
         
            -
                    batch_limit 
     | 
| 
      
 16 
     | 
    
         
            +
                    batch_limit = [batch_size, total_limit - batch_offset].min
         
     | 
| 
       17 
17 
     | 
    
         
             
                    results, offset_id = reader.call(offset_id, batch_limit)
         
     | 
| 
       18 
18 
     | 
    
         | 
| 
       19 
19 
     | 
    
         
             
                    break if results.empty?
         
     | 
| 
         @@ -34,4 +34,3 @@ module RailsEventStoreActiveRecord 
     | 
|
| 
       34 
34 
     | 
    
         
             
                attr_reader :batch_size, :total_limit, :reader
         
     | 
| 
       35 
35 
     | 
    
         
             
              end
         
     | 
| 
       36 
36 
     | 
    
         
             
            end
         
     | 
| 
       37 
     | 
    
         
            -
             
     | 
| 
         @@ -1,16 +1,16 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            # frozen_string_literal: true
         
     | 
| 
       2 
2 
     | 
    
         | 
| 
       3 
     | 
    
         
            -
            require  
     | 
| 
      
 3 
     | 
    
         
            +
            require "active_record"
         
     | 
| 
       4 
4 
     | 
    
         | 
| 
       5 
5 
     | 
    
         
             
            module RailsEventStoreActiveRecord
         
     | 
| 
       6 
6 
     | 
    
         
             
              class Event < ::ActiveRecord::Base
         
     | 
| 
       7 
7 
     | 
    
         
             
                self.primary_key = :id
         
     | 
| 
       8 
     | 
    
         
            -
                self.table_name =  
     | 
| 
      
 8 
     | 
    
         
            +
                self.table_name = "event_store_events"
         
     | 
| 
       9 
9 
     | 
    
         
             
              end
         
     | 
| 
       10 
10 
     | 
    
         | 
| 
       11 
11 
     | 
    
         
             
              class EventInStream < ::ActiveRecord::Base
         
     | 
| 
       12 
12 
     | 
    
         
             
                self.primary_key = :id
         
     | 
| 
       13 
     | 
    
         
            -
                self.table_name =  
     | 
| 
      
 13 
     | 
    
         
            +
                self.table_name = "event_store_events_in_streams"
         
     | 
| 
       14 
14 
     | 
    
         
             
                belongs_to :event, primary_key: :event_id
         
     | 
| 
       15 
15 
     | 
    
         
             
              end
         
     | 
| 
       16 
16 
     | 
    
         
             
            end
         
     | 
| 
         @@ -1,14 +1,13 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            # frozen_string_literal: true
         
     | 
| 
       2 
2 
     | 
    
         | 
| 
       3 
     | 
    
         
            -
            require  
     | 
| 
       4 
     | 
    
         
            -
            require 'activerecord-import'
         
     | 
| 
      
 3 
     | 
    
         
            +
            require "active_support/core_ext/array"
         
     | 
| 
       5 
4 
     | 
    
         | 
| 
       6 
5 
     | 
    
         
             
            module RailsEventStoreActiveRecord
         
     | 
| 
       7 
6 
     | 
    
         
             
              class EventRepository
         
     | 
| 
       8 
7 
     | 
    
         
             
                POSITION_SHIFT = 1
         
     | 
| 
       9 
8 
     | 
    
         | 
| 
       10 
9 
     | 
    
         
             
                def initialize(model_factory: WithDefaultModels.new, serializer:)
         
     | 
| 
       11 
     | 
    
         
            -
                  @serializer 
     | 
| 
      
 10 
     | 
    
         
            +
                  @serializer = serializer
         
     | 
| 
       12 
11 
     | 
    
         | 
| 
       13 
12 
     | 
    
         
             
                  @event_klass, @stream_klass = model_factory.call
         
     | 
| 
       14 
13 
     | 
    
         
             
                  @repo_reader = EventRepositoryReader.new(@event_klass, @stream_klass, serializer)
         
     | 
| 
         @@ -16,15 +15,13 @@ module RailsEventStoreActiveRecord 
     | 
|
| 
       16 
15 
     | 
    
         
             
                end
         
     | 
| 
       17 
16 
     | 
    
         | 
| 
       18 
17 
     | 
    
         
             
                def append_to_stream(records, stream, expected_version)
         
     | 
| 
       19 
     | 
    
         
            -
                  hashes 
     | 
| 
      
 18 
     | 
    
         
            +
                  hashes = []
         
     | 
| 
       20 
19 
     | 
    
         
             
                  event_ids = []
         
     | 
| 
       21 
20 
     | 
    
         
             
                  records.each do |record|
         
     | 
| 
       22 
     | 
    
         
            -
                    hashes 
     | 
| 
      
 21 
     | 
    
         
            +
                    hashes << insert_hash(record, record.serialize(serializer))
         
     | 
| 
       23 
22 
     | 
    
         
             
                    event_ids << record.event_id
         
     | 
| 
       24 
23 
     | 
    
         
             
                  end
         
     | 
| 
       25 
     | 
    
         
            -
                  add_to_stream(event_ids, stream, expected_version)  
     | 
| 
       26 
     | 
    
         
            -
                    @event_klass.import(hashes)
         
     | 
| 
       27 
     | 
    
         
            -
                  end
         
     | 
| 
      
 24 
     | 
    
         
            +
                  add_to_stream(event_ids, stream, expected_version) { @event_klass.insert_all!(hashes) }
         
     | 
| 
       28 
25 
     | 
    
         
             
                end
         
     | 
| 
       29 
26 
     | 
    
         | 
| 
       30 
27 
     | 
    
         
             
                def link_to_stream(event_ids, stream, expected_version)
         
     | 
| 
         @@ -55,39 +52,61 @@ module RailsEventStoreActiveRecord 
     | 
|
| 
       55 
52 
     | 
    
         
             
                end
         
     | 
| 
       56 
53 
     | 
    
         | 
| 
       57 
54 
     | 
    
         
             
                def update_messages(records)
         
     | 
| 
       58 
     | 
    
         
            -
                  hashes 
     | 
| 
      
 55 
     | 
    
         
            +
                  hashes = records.map { |record| upsert_hash(record, record.serialize(serializer)) }
         
     | 
| 
       59 
56 
     | 
    
         
             
                  for_update = records.map(&:event_id)
         
     | 
| 
       60 
57 
     | 
    
         
             
                  start_transaction do
         
     | 
| 
       61 
     | 
    
         
            -
                    existing = 
     | 
| 
       62 
     | 
    
         
            -
             
     | 
| 
       63 
     | 
    
         
            -
             
     | 
| 
       64 
     | 
    
         
            -
             
     | 
| 
      
 58 
     | 
    
         
            +
                    existing =
         
     | 
| 
      
 59 
     | 
    
         
            +
                      @event_klass
         
     | 
| 
      
 60 
     | 
    
         
            +
                        .where(event_id: for_update)
         
     | 
| 
      
 61 
     | 
    
         
            +
                        .pluck(:event_id, :id, :created_at)
         
     | 
| 
      
 62 
     | 
    
         
            +
                        .reduce({}) { |acc, (event_id, id, created_at)| acc.merge(event_id => [id, created_at]) }
         
     | 
| 
      
 63 
     | 
    
         
            +
                    (for_update - existing.keys).each { |id| raise RubyEventStore::EventNotFound.new(id) }
         
     | 
| 
      
 64 
     | 
    
         
            +
                    hashes.each do |h|
         
     | 
| 
      
 65 
     | 
    
         
            +
                      h[:id] = existing.fetch(h.fetch(:event_id)).at(0)
         
     | 
| 
      
 66 
     | 
    
         
            +
                      h[:created_at] = existing.fetch(h.fetch(:event_id)).at(1)
         
     | 
| 
      
 67 
     | 
    
         
            +
                    end
         
     | 
| 
      
 68 
     | 
    
         
            +
                    @event_klass.upsert_all(hashes)
         
     | 
| 
       65 
69 
     | 
    
         
             
                  end
         
     | 
| 
       66 
70 
     | 
    
         
             
                end
         
     | 
| 
       67 
71 
     | 
    
         | 
| 
       68 
72 
     | 
    
         
             
                def streams_of(event_id)
         
     | 
| 
       69 
     | 
    
         
            -
                  @ 
     | 
| 
       70 
     | 
    
         
            -
             
     | 
| 
       71 
     | 
    
         
            -
             
     | 
| 
      
 73 
     | 
    
         
            +
                  @repo_reader.streams_of(event_id)
         
     | 
| 
      
 74 
     | 
    
         
            +
                end
         
     | 
| 
      
 75 
     | 
    
         
            +
             
     | 
| 
      
 76 
     | 
    
         
            +
                def position_in_stream(event_id, stream)
         
     | 
| 
      
 77 
     | 
    
         
            +
                  @repo_reader.position_in_stream(event_id, stream)
         
     | 
| 
      
 78 
     | 
    
         
            +
                end
         
     | 
| 
      
 79 
     | 
    
         
            +
             
     | 
| 
      
 80 
     | 
    
         
            +
                def global_position(event_id)
         
     | 
| 
      
 81 
     | 
    
         
            +
                  @repo_reader.global_position(event_id)
         
     | 
| 
      
 82 
     | 
    
         
            +
                end
         
     | 
| 
      
 83 
     | 
    
         
            +
             
     | 
| 
      
 84 
     | 
    
         
            +
                def event_in_stream?(event_id, stream)
         
     | 
| 
      
 85 
     | 
    
         
            +
                  @repo_reader.event_in_stream?(event_id, stream)
         
     | 
| 
       72 
86 
     | 
    
         
             
                end
         
     | 
| 
       73 
87 
     | 
    
         | 
| 
       74 
88 
     | 
    
         
             
                private
         
     | 
| 
      
 89 
     | 
    
         
            +
             
     | 
| 
       75 
90 
     | 
    
         
             
                attr_reader :serializer
         
     | 
| 
       76 
91 
     | 
    
         | 
| 
       77 
92 
     | 
    
         
             
                def add_to_stream(event_ids, stream, expected_version)
         
     | 
| 
       78 
     | 
    
         
            -
                  last_stream_version = ->(stream_)  
     | 
| 
      
 93 
     | 
    
         
            +
                  last_stream_version = ->(stream_) do
         
     | 
| 
      
 94 
     | 
    
         
            +
                    @stream_klass.where(stream: stream_.name).order("position DESC").first.try(:position)
         
     | 
| 
      
 95 
     | 
    
         
            +
                  end
         
     | 
| 
       79 
96 
     | 
    
         
             
                  resolved_version = expected_version.resolve_for(stream, last_stream_version)
         
     | 
| 
       80 
97 
     | 
    
         | 
| 
       81 
98 
     | 
    
         
             
                  start_transaction do
         
     | 
| 
       82 
99 
     | 
    
         
             
                    yield if block_given?
         
     | 
| 
       83 
     | 
    
         
            -
                    in_stream = 
     | 
| 
       84 
     | 
    
         
            -
                       
     | 
| 
       85 
     | 
    
         
            -
                         
     | 
| 
       86 
     | 
    
         
            -
             
     | 
| 
       87 
     | 
    
         
            -
             
     | 
| 
       88 
     | 
    
         
            -
             
     | 
| 
       89 
     | 
    
         
            -
             
     | 
| 
       90 
     | 
    
         
            -
             
     | 
| 
      
 100 
     | 
    
         
            +
                    in_stream =
         
     | 
| 
      
 101 
     | 
    
         
            +
                      event_ids.map.with_index do |event_id, index|
         
     | 
| 
      
 102 
     | 
    
         
            +
                        {
         
     | 
| 
      
 103 
     | 
    
         
            +
                          stream: stream.name,
         
     | 
| 
      
 104 
     | 
    
         
            +
                          position: compute_position(resolved_version, index),
         
     | 
| 
      
 105 
     | 
    
         
            +
                          event_id: event_id,
         
     | 
| 
      
 106 
     | 
    
         
            +
                          created_at: Time.now.utc
         
     | 
| 
      
 107 
     | 
    
         
            +
                        }
         
     | 
| 
      
 108 
     | 
    
         
            +
                      end
         
     | 
| 
      
 109 
     | 
    
         
            +
                    @stream_klass.insert_all!(in_stream) unless stream.global?
         
     | 
| 
       91 
110 
     | 
    
         
             
                  end
         
     | 
| 
       92 
111 
     | 
    
         
             
                  self
         
     | 
| 
       93 
112 
     | 
    
         
             
                rescue ActiveRecord::RecordNotUnique => e
         
     | 
| 
         @@ -95,30 +114,36 @@ module RailsEventStoreActiveRecord 
     | 
|
| 
       95 
114 
     | 
    
         
             
                end
         
     | 
| 
       96 
115 
     | 
    
         | 
| 
       97 
116 
     | 
    
         
             
                def raise_error(e)
         
     | 
| 
       98 
     | 
    
         
            -
                  if detect_index_violated(e.message)
         
     | 
| 
       99 
     | 
    
         
            -
                    raise RubyEventStore::EventDuplicatedInStream
         
     | 
| 
       100 
     | 
    
         
            -
                  end
         
     | 
| 
      
 117 
     | 
    
         
            +
                  raise RubyEventStore::EventDuplicatedInStream if detect_index_violated(e.message)
         
     | 
| 
       101 
118 
     | 
    
         
             
                  raise RubyEventStore::WrongExpectedEventVersion
         
     | 
| 
       102 
119 
     | 
    
         
             
                end
         
     | 
| 
       103 
120 
     | 
    
         | 
| 
       104 
121 
     | 
    
         
             
                def compute_position(resolved_version, index)
         
     | 
| 
       105 
     | 
    
         
            -
                  unless resolved_version.nil?
         
     | 
| 
       106 
     | 
    
         
            -
                    resolved_version + index + POSITION_SHIFT
         
     | 
| 
       107 
     | 
    
         
            -
                  end
         
     | 
| 
      
 122 
     | 
    
         
            +
                  resolved_version + index + POSITION_SHIFT unless resolved_version.nil?
         
     | 
| 
       108 
123 
     | 
    
         
             
                end
         
     | 
| 
       109 
124 
     | 
    
         | 
| 
       110 
125 
     | 
    
         
             
                def detect_index_violated(message)
         
     | 
| 
       111 
126 
     | 
    
         
             
                  @index_violation_detector.detect(message)
         
     | 
| 
       112 
127 
     | 
    
         
             
                end
         
     | 
| 
       113 
128 
     | 
    
         | 
| 
       114 
     | 
    
         
            -
                def  
     | 
| 
      
 129 
     | 
    
         
            +
                def insert_hash(record, serialized_record)
         
     | 
| 
       115 
130 
     | 
    
         
             
                  {
         
     | 
| 
       116 
     | 
    
         
            -
                    event_id: 
     | 
| 
       117 
     | 
    
         
            -
                    data: 
     | 
| 
       118 
     | 
    
         
            -
                    metadata: 
     | 
| 
      
 131 
     | 
    
         
            +
                    event_id: serialized_record.event_id,
         
     | 
| 
      
 132 
     | 
    
         
            +
                    data: serialized_record.data,
         
     | 
| 
      
 133 
     | 
    
         
            +
                    metadata: serialized_record.metadata,
         
     | 
| 
       119 
134 
     | 
    
         
             
                    event_type: serialized_record.event_type,
         
     | 
| 
       120 
135 
     | 
    
         
             
                    created_at: record.timestamp,
         
     | 
| 
       121 
     | 
    
         
            -
                    valid_at: 
     | 
| 
      
 136 
     | 
    
         
            +
                    valid_at: optimize_timestamp(record.valid_at, record.timestamp)
         
     | 
| 
      
 137 
     | 
    
         
            +
                  }
         
     | 
| 
      
 138 
     | 
    
         
            +
                end
         
     | 
| 
      
 139 
     | 
    
         
            +
             
     | 
| 
      
 140 
     | 
    
         
            +
                def upsert_hash(record, serialized_record)
         
     | 
| 
      
 141 
     | 
    
         
            +
                  {
         
     | 
| 
      
 142 
     | 
    
         
            +
                    event_id: serialized_record.event_id,
         
     | 
| 
      
 143 
     | 
    
         
            +
                    data: serialized_record.data,
         
     | 
| 
      
 144 
     | 
    
         
            +
                    metadata: serialized_record.metadata,
         
     | 
| 
      
 145 
     | 
    
         
            +
                    event_type: serialized_record.event_type,
         
     | 
| 
      
 146 
     | 
    
         
            +
                    valid_at: optimize_timestamp(record.valid_at, record.timestamp)
         
     | 
| 
       122 
147 
     | 
    
         
             
                  }
         
     | 
| 
       123 
148 
     | 
    
         
             
                end
         
     | 
| 
       124 
149 
     | 
    
         | 
| 
         @@ -130,5 +155,4 @@ module RailsEventStoreActiveRecord 
     | 
|
| 
       130 
155 
     | 
    
         
             
                  @event_klass.transaction(requires_new: true, &block)
         
     | 
| 
       131 
156 
     | 
    
         
             
                end
         
     | 
| 
       132 
157 
     | 
    
         
             
              end
         
     | 
| 
       133 
     | 
    
         
            -
             
     | 
| 
       134 
158 
     | 
    
         
             
            end
         
     | 
| 
         @@ -2,7 +2,6 @@ 
     | 
|
| 
       2 
2 
     | 
    
         | 
| 
       3 
3 
     | 
    
         
             
            module RailsEventStoreActiveRecord
         
     | 
| 
       4 
4 
     | 
    
         
             
              class EventRepositoryReader
         
     | 
| 
       5 
     | 
    
         
            -
             
     | 
| 
       6 
5 
     | 
    
         
             
                def initialize(event_klass, stream_klass, serializer)
         
     | 
| 
       7 
6 
     | 
    
         
             
                  @event_klass = event_klass
         
     | 
| 
       8 
7 
     | 
    
         
             
                  @stream_klass = stream_klass
         
     | 
| 
         @@ -14,20 +13,14 @@ module RailsEventStoreActiveRecord 
     | 
|
| 
       14 
13 
     | 
    
         
             
                end
         
     | 
| 
       15 
14 
     | 
    
         | 
| 
       16 
15 
     | 
    
         
             
                def last_stream_event(stream)
         
     | 
| 
       17 
     | 
    
         
            -
                  record_ = @stream_klass.where(stream: stream.name).order( 
     | 
| 
      
 16 
     | 
    
         
            +
                  record_ = @stream_klass.where(stream: stream.name).order("position DESC, id DESC").first
         
     | 
| 
       18 
17 
     | 
    
         
             
                  record(record_) if record_
         
     | 
| 
       19 
18 
     | 
    
         
             
                end
         
     | 
| 
       20 
19 
     | 
    
         | 
| 
       21 
20 
     | 
    
         
             
                def read(spec)
         
     | 
| 
       22 
21 
     | 
    
         
             
                  stream = read_scope(spec)
         
     | 
| 
       23 
     | 
    
         
            -
             
     | 
| 
       24 
22 
     | 
    
         
             
                  if spec.batched?
         
     | 
| 
       25 
     | 
    
         
            -
                     
     | 
| 
       26 
     | 
    
         
            -
                      search_in = spec.stream.global? ? @event_klass.table_name : @stream_klass.table_name
         
     | 
| 
       27 
     | 
    
         
            -
                      records = offset_id.nil? ? stream.limit(limit) : stream.where(start_offset_condition(spec, offset_id, search_in)).limit(limit)
         
     | 
| 
       28 
     | 
    
         
            -
                      [records.map(&method(:record)), records.last]
         
     | 
| 
       29 
     | 
    
         
            -
                    end
         
     | 
| 
       30 
     | 
    
         
            -
                    BatchEnumerator.new(spec.batch_size, spec.limit, batch_reader).each
         
     | 
| 
      
 23 
     | 
    
         
            +
                    spec.time_sort_by ? offset_limit_batch_reader(spec, stream) : monotonic_id_batch_reader(spec, stream)
         
     | 
| 
       31 
24 
     | 
    
         
             
                  elsif spec.first?
         
     | 
| 
       32 
25 
     | 
    
         
             
                    record_ = stream.first
         
     | 
| 
       33 
26 
     | 
    
         
             
                    record(record_) if record_
         
     | 
| 
         @@ -43,35 +36,75 @@ module RailsEventStoreActiveRecord 
     | 
|
| 
       43 
36 
     | 
    
         
             
                  read_scope(spec).count
         
     | 
| 
       44 
37 
     | 
    
         
             
                end
         
     | 
| 
       45 
38 
     | 
    
         | 
| 
      
 39 
     | 
    
         
            +
                def streams_of(event_id)
         
     | 
| 
      
 40 
     | 
    
         
            +
                  @stream_klass.where(event_id: event_id).pluck(:stream).map { |name| RubyEventStore::Stream.new(name) }
         
     | 
| 
      
 41 
     | 
    
         
            +
                end
         
     | 
| 
      
 42 
     | 
    
         
            +
             
     | 
| 
      
 43 
     | 
    
         
            +
                def position_in_stream(event_id, stream)
         
     | 
| 
      
 44 
     | 
    
         
            +
                  record = @stream_klass.select("position").where(stream: stream.name).find_by(event_id: event_id)
         
     | 
| 
      
 45 
     | 
    
         
            +
                  raise RubyEventStore::EventNotFoundInStream if record.nil?
         
     | 
| 
      
 46 
     | 
    
         
            +
                  record.position
         
     | 
| 
      
 47 
     | 
    
         
            +
                end
         
     | 
| 
      
 48 
     | 
    
         
            +
             
     | 
| 
      
 49 
     | 
    
         
            +
                def global_position(event_id)
         
     | 
| 
      
 50 
     | 
    
         
            +
                  record = @event_klass.select("id").find_by(event_id: event_id)
         
     | 
| 
      
 51 
     | 
    
         
            +
                  raise RubyEventStore::EventNotFound.new(event_id) if record.nil?
         
     | 
| 
      
 52 
     | 
    
         
            +
                  record.id - 1
         
     | 
| 
      
 53 
     | 
    
         
            +
                end
         
     | 
| 
      
 54 
     | 
    
         
            +
             
     | 
| 
      
 55 
     | 
    
         
            +
                def event_in_stream?(event_id, stream)
         
     | 
| 
      
 56 
     | 
    
         
            +
                  @stream_klass.where(event_id: event_id, stream: stream.name).exists?
         
     | 
| 
      
 57 
     | 
    
         
            +
                end
         
     | 
| 
      
 58 
     | 
    
         
            +
             
     | 
| 
       46 
59 
     | 
    
         
             
                private
         
     | 
| 
      
 60 
     | 
    
         
            +
             
     | 
| 
       47 
61 
     | 
    
         
             
                attr_reader :serializer
         
     | 
| 
       48 
62 
     | 
    
         | 
| 
      
 63 
     | 
    
         
            +
                def offset_limit_batch_reader(spec, stream)
         
     | 
| 
      
 64 
     | 
    
         
            +
                  batch_reader = ->(offset, limit) { stream.offset(offset).limit(limit).map(&method(:record)) }
         
     | 
| 
      
 65 
     | 
    
         
            +
                  RubyEventStore::BatchEnumerator.new(spec.batch_size, spec.limit, batch_reader).each
         
     | 
| 
      
 66 
     | 
    
         
            +
                end
         
     | 
| 
      
 67 
     | 
    
         
            +
             
     | 
| 
      
 68 
     | 
    
         
            +
                def monotonic_id_batch_reader(spec, stream)
         
     | 
| 
      
 69 
     | 
    
         
            +
                  batch_reader = ->(offset_id, limit) do
         
     | 
| 
      
 70 
     | 
    
         
            +
                    search_in = spec.stream.global? ? @event_klass.table_name : @stream_klass.table_name
         
     | 
| 
      
 71 
     | 
    
         
            +
                    records =
         
     | 
| 
      
 72 
     | 
    
         
            +
                      if offset_id.nil?
         
     | 
| 
      
 73 
     | 
    
         
            +
                        stream.limit(limit)
         
     | 
| 
      
 74 
     | 
    
         
            +
                      else
         
     | 
| 
      
 75 
     | 
    
         
            +
                        stream.where(start_offset_condition(spec, offset_id, search_in)).limit(limit)
         
     | 
| 
      
 76 
     | 
    
         
            +
                      end
         
     | 
| 
      
 77 
     | 
    
         
            +
                    [records.map(&method(:record)), records.last]
         
     | 
| 
      
 78 
     | 
    
         
            +
                  end
         
     | 
| 
      
 79 
     | 
    
         
            +
                  BatchEnumerator.new(spec.batch_size, spec.limit, batch_reader).each
         
     | 
| 
      
 80 
     | 
    
         
            +
                end
         
     | 
| 
      
 81 
     | 
    
         
            +
             
     | 
| 
       49 
82 
     | 
    
         
             
                def read_scope(spec)
         
     | 
| 
       50 
83 
     | 
    
         
             
                  if spec.stream.global?
         
     | 
| 
       51 
84 
     | 
    
         
             
                    stream = @event_klass
         
     | 
| 
       52 
     | 
    
         
            -
                    stream = stream.where(event_id: spec.with_ids) 
     | 
| 
       53 
     | 
    
         
            -
                    stream = stream.where(event_type: spec.with_types) 
     | 
| 
      
 85 
     | 
    
         
            +
                    stream = stream.where(event_id: spec.with_ids) if spec.with_ids?
         
     | 
| 
      
 86 
     | 
    
         
            +
                    stream = stream.where(event_type: spec.with_types) if spec.with_types?
         
     | 
| 
       54 
87 
     | 
    
         
             
                    stream = ordered(stream, spec)
         
     | 
| 
       55 
     | 
    
         
            -
                    stream = stream.limit(spec.limit) 
     | 
| 
       56 
     | 
    
         
            -
                    stream = stream.where(start_condition_in_global_stream(spec)) 
     | 
| 
       57 
     | 
    
         
            -
                    stream = stream.where(stop_condition_in_global_stream(spec)) 
     | 
| 
       58 
     | 
    
         
            -
                    stream = stream.where(older_than_condition(spec)) 
     | 
| 
      
 88 
     | 
    
         
            +
                    stream = stream.limit(spec.limit) if spec.limit?
         
     | 
| 
      
 89 
     | 
    
         
            +
                    stream = stream.where(start_condition_in_global_stream(spec)) if spec.start
         
     | 
| 
      
 90 
     | 
    
         
            +
                    stream = stream.where(stop_condition_in_global_stream(spec)) if spec.stop
         
     | 
| 
      
 91 
     | 
    
         
            +
                    stream = stream.where(older_than_condition(spec)) if spec.older_than
         
     | 
| 
       59 
92 
     | 
    
         
             
                    stream = stream.where(older_than_or_equal_condition(spec)) if spec.older_than_or_equal
         
     | 
| 
       60 
     | 
    
         
            -
                    stream = stream.where(newer_than_condition(spec)) 
     | 
| 
      
 93 
     | 
    
         
            +
                    stream = stream.where(newer_than_condition(spec)) if spec.newer_than
         
     | 
| 
       61 
94 
     | 
    
         
             
                    stream = stream.where(newer_than_or_equal_condition(spec)) if spec.newer_than_or_equal
         
     | 
| 
       62 
95 
     | 
    
         
             
                    stream.order(id: order(spec))
         
     | 
| 
       63 
96 
     | 
    
         
             
                  else
         
     | 
| 
       64 
97 
     | 
    
         
             
                    stream = @stream_klass.preload(:event).where(stream: spec.stream.name)
         
     | 
| 
       65 
     | 
    
         
            -
                    stream = stream.where(event_id: spec.with_ids) 
     | 
| 
       66 
     | 
    
         
            -
                    stream = stream.where(@event_klass.table_name => {event_type: spec.with_types}) if spec.with_types?
         
     | 
| 
      
 98 
     | 
    
         
            +
                    stream = stream.where(event_id: spec.with_ids) if spec.with_ids?
         
     | 
| 
      
 99 
     | 
    
         
            +
                    stream = stream.where(@event_klass.table_name => { event_type: spec.with_types }) if spec.with_types?
         
     | 
| 
       67 
100 
     | 
    
         
             
                    stream = ordered(stream.joins(:event), spec)
         
     | 
| 
       68 
     | 
    
         
            -
                    stream = stream.order( 
     | 
| 
       69 
     | 
    
         
            -
                    stream = stream.limit(spec.limit) 
     | 
| 
       70 
     | 
    
         
            -
                    stream = stream.where(start_condition(spec)) 
     | 
| 
       71 
     | 
    
         
            -
                    stream = stream.where(stop_condition(spec)) 
     | 
| 
       72 
     | 
    
         
            -
                    stream = stream.where(older_than_condition(spec)) 
     | 
| 
      
 101 
     | 
    
         
            +
                    stream = stream.order(id: order(spec))
         
     | 
| 
      
 102 
     | 
    
         
            +
                    stream = stream.limit(spec.limit) if spec.limit?
         
     | 
| 
      
 103 
     | 
    
         
            +
                    stream = stream.where(start_condition(spec)) if spec.start
         
     | 
| 
      
 104 
     | 
    
         
            +
                    stream = stream.where(stop_condition(spec)) if spec.stop
         
     | 
| 
      
 105 
     | 
    
         
            +
                    stream = stream.where(older_than_condition(spec)) if spec.older_than
         
     | 
| 
       73 
106 
     | 
    
         
             
                    stream = stream.where(older_than_or_equal_condition(spec)) if spec.older_than_or_equal
         
     | 
| 
       74 
     | 
    
         
            -
                    stream = stream.where(newer_than_condition(spec)) 
     | 
| 
      
 107 
     | 
    
         
            +
                    stream = stream.where(newer_than_condition(spec)) if spec.newer_than
         
     | 
| 
       75 
108 
     | 
    
         
             
                    stream = stream.where(newer_than_or_equal_condition(spec)) if spec.newer_than_or_equal
         
     | 
| 
       76 
109 
     | 
    
         
             
                    stream
         
     | 
| 
       77 
110 
     | 
    
         
             
                  end
         
     | 
| 
         @@ -89,37 +122,41 @@ module RailsEventStoreActiveRecord 
     | 
|
| 
       89 
122 
     | 
    
         
             
                end
         
     | 
| 
       90 
123 
     | 
    
         | 
| 
       91 
124 
     | 
    
         
             
                def start_offset_condition(specification, record_id, search_in)
         
     | 
| 
       92 
     | 
    
         
            -
                  condition = "#{search_in}.id #{specification.forward? ?  
     | 
| 
      
 125 
     | 
    
         
            +
                  condition = "#{search_in}.id #{specification.forward? ? ">" : "<"} ?"
         
     | 
| 
       93 
126 
     | 
    
         
             
                  [condition, record_id]
         
     | 
| 
       94 
127 
     | 
    
         
             
                end
         
     | 
| 
       95 
128 
     | 
    
         | 
| 
       96 
129 
     | 
    
         
             
                def stop_offset_condition(specification, record_id, search_in)
         
     | 
| 
       97 
     | 
    
         
            -
                  condition = "#{search_in}.id #{specification.forward? ?  
     | 
| 
      
 130 
     | 
    
         
            +
                  condition = "#{search_in}.id #{specification.forward? ? "<" : ">"} ?"
         
     | 
| 
       98 
131 
     | 
    
         
             
                  [condition, record_id]
         
     | 
| 
       99 
132 
     | 
    
         
             
                end
         
     | 
| 
       100 
133 
     | 
    
         | 
| 
       101 
134 
     | 
    
         
             
                def start_condition(specification)
         
     | 
| 
       102 
     | 
    
         
            -
                  start_offset_condition( 
     | 
| 
      
 135 
     | 
    
         
            +
                  start_offset_condition(
         
     | 
| 
      
 136 
     | 
    
         
            +
                    specification,
         
     | 
| 
       103 
137 
     | 
    
         
             
                    @stream_klass.find_by!(event_id: specification.start, stream: specification.stream.name),
         
     | 
| 
       104 
     | 
    
         
            -
                    @stream_klass.table_name 
     | 
| 
      
 138 
     | 
    
         
            +
                    @stream_klass.table_name
         
     | 
| 
      
 139 
     | 
    
         
            +
                  )
         
     | 
| 
       105 
140 
     | 
    
         
             
                end
         
     | 
| 
       106 
141 
     | 
    
         | 
| 
       107 
142 
     | 
    
         
             
                def stop_condition(specification)
         
     | 
| 
       108 
     | 
    
         
            -
                  stop_offset_condition( 
     | 
| 
      
 143 
     | 
    
         
            +
                  stop_offset_condition(
         
     | 
| 
      
 144 
     | 
    
         
            +
                    specification,
         
     | 
| 
       109 
145 
     | 
    
         
             
                    @stream_klass.find_by!(event_id: specification.stop, stream: specification.stream.name),
         
     | 
| 
       110 
     | 
    
         
            -
                    @stream_klass.table_name 
     | 
| 
      
 146 
     | 
    
         
            +
                    @stream_klass.table_name
         
     | 
| 
      
 147 
     | 
    
         
            +
                  )
         
     | 
| 
       111 
148 
     | 
    
         
             
                end
         
     | 
| 
       112 
149 
     | 
    
         | 
| 
       113 
150 
     | 
    
         
             
                def start_condition_in_global_stream(specification)
         
     | 
| 
       114 
     | 
    
         
            -
                  start_offset_condition( 
     | 
| 
      
 151 
     | 
    
         
            +
                  start_offset_condition(
         
     | 
| 
      
 152 
     | 
    
         
            +
                    specification,
         
     | 
| 
       115 
153 
     | 
    
         
             
                    @event_klass.find_by!(event_id: specification.start),
         
     | 
| 
       116 
     | 
    
         
            -
                    @event_klass.table_name 
     | 
| 
      
 154 
     | 
    
         
            +
                    @event_klass.table_name
         
     | 
| 
      
 155 
     | 
    
         
            +
                  )
         
     | 
| 
       117 
156 
     | 
    
         
             
                end
         
     | 
| 
       118 
157 
     | 
    
         | 
| 
       119 
158 
     | 
    
         
             
                def stop_condition_in_global_stream(specification)
         
     | 
| 
       120 
     | 
    
         
            -
                  stop_offset_condition(specification,
         
     | 
| 
       121 
     | 
    
         
            -
                    @event_klass.find_by!(event_id: specification.stop),
         
     | 
| 
       122 
     | 
    
         
            -
                    @event_klass.table_name)
         
     | 
| 
      
 159 
     | 
    
         
            +
                  stop_offset_condition(specification, @event_klass.find_by!(event_id: specification.stop), @event_klass.table_name)
         
     | 
| 
       123 
160 
     | 
    
         
             
                end
         
     | 
| 
       124 
161 
     | 
    
         | 
| 
       125 
162 
     | 
    
         
             
                def older_than_condition(specification)
         
     | 
| 
         @@ -139,20 +176,22 @@ module RailsEventStoreActiveRecord 
     | 
|
| 
       139 
176 
     | 
    
         
             
                end
         
     | 
| 
       140 
177 
     | 
    
         | 
| 
       141 
178 
     | 
    
         
             
                def order(spec)
         
     | 
| 
       142 
     | 
    
         
            -
                  spec.forward? ?  
     | 
| 
      
 179 
     | 
    
         
            +
                  spec.forward? ? "ASC" : "DESC"
         
     | 
| 
       143 
180 
     | 
    
         
             
                end
         
     | 
| 
       144 
181 
     | 
    
         | 
| 
       145 
182 
     | 
    
         
             
                def record(record)
         
     | 
| 
       146 
183 
     | 
    
         
             
                  record = record.event if @stream_klass === record
         
     | 
| 
       147 
184 
     | 
    
         | 
| 
       148 
     | 
    
         
            -
                  RubyEventStore::SerializedRecord 
     | 
| 
       149 
     | 
    
         
            -
                     
     | 
| 
       150 
     | 
    
         
            -
             
     | 
| 
       151 
     | 
    
         
            -
             
     | 
| 
       152 
     | 
    
         
            -
             
     | 
| 
       153 
     | 
    
         
            -
             
     | 
| 
       154 
     | 
    
         
            -
             
     | 
| 
       155 
     | 
    
         
            -
             
     | 
| 
      
 185 
     | 
    
         
            +
                  RubyEventStore::SerializedRecord
         
     | 
| 
      
 186 
     | 
    
         
            +
                    .new(
         
     | 
| 
      
 187 
     | 
    
         
            +
                      event_id: record.event_id,
         
     | 
| 
      
 188 
     | 
    
         
            +
                      metadata: record.metadata,
         
     | 
| 
      
 189 
     | 
    
         
            +
                      data: record.data,
         
     | 
| 
      
 190 
     | 
    
         
            +
                      event_type: record.event_type,
         
     | 
| 
      
 191 
     | 
    
         
            +
                      timestamp: record.created_at.iso8601(RubyEventStore::TIMESTAMP_PRECISION),
         
     | 
| 
      
 192 
     | 
    
         
            +
                      valid_at: (record.valid_at || record.created_at).iso8601(RubyEventStore::TIMESTAMP_PRECISION)
         
     | 
| 
      
 193 
     | 
    
         
            +
                    )
         
     | 
| 
      
 194 
     | 
    
         
            +
                    .deserialize(serializer)
         
     | 
| 
       156 
195 
     | 
    
         
             
                end
         
     | 
| 
       157 
196 
     | 
    
         
             
              end
         
     | 
| 
       158 
197 
     | 
    
         | 
| 
         @@ -1,22 +1,24 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            # frozen_string_literal: true
         
     | 
| 
       2 
2 
     | 
    
         | 
| 
       3 
3 
     | 
    
         
             
            begin
         
     | 
| 
       4 
     | 
    
         
            -
              require  
     | 
| 
      
 4 
     | 
    
         
            +
              require "rails/generators"
         
     | 
| 
       5 
5 
     | 
    
         
             
            rescue LoadError
         
     | 
| 
       6 
6 
     | 
    
         
             
            end
         
     | 
| 
       7 
7 
     | 
    
         | 
| 
       8 
8 
     | 
    
         
             
            module RailsEventStoreActiveRecord
         
     | 
| 
       9 
9 
     | 
    
         
             
              class MigrationGenerator < Rails::Generators::Base
         
     | 
| 
       10 
     | 
    
         
            -
                class Error < Thor::Error 
     | 
| 
      
 10 
     | 
    
         
            +
                class Error < Thor::Error
         
     | 
| 
      
 11 
     | 
    
         
            +
                end
         
     | 
| 
       11 
12 
     | 
    
         | 
| 
       12 
     | 
    
         
            -
                DATA_TYPES = %w 
     | 
| 
      
 13 
     | 
    
         
            +
                DATA_TYPES = %w[binary json jsonb].freeze
         
     | 
| 
       13 
14 
     | 
    
         | 
| 
       14 
     | 
    
         
            -
                source_root File.expand_path(File.join(File.dirname(__FILE__),  
     | 
| 
      
 15 
     | 
    
         
            +
                source_root File.expand_path(File.join(File.dirname(__FILE__), "../generators/templates"))
         
     | 
| 
       15 
16 
     | 
    
         
             
                class_option(
         
     | 
| 
       16 
17 
     | 
    
         
             
                  :data_type,
         
     | 
| 
       17 
18 
     | 
    
         
             
                  type: :string,
         
     | 
| 
       18 
     | 
    
         
            -
                  default:  
     | 
| 
       19 
     | 
    
         
            -
                  desc: 
     | 
| 
      
 19 
     | 
    
         
            +
                  default: "binary",
         
     | 
| 
      
 20 
     | 
    
         
            +
                  desc:
         
     | 
| 
      
 21 
     | 
    
         
            +
                    "Configure the data type for `data` and `meta data` fields in Postgres migration (options: #{DATA_TYPES.join("/")})"
         
     | 
| 
       20 
22 
     | 
    
         
             
                )
         
     | 
| 
       21 
23 
     | 
    
         | 
| 
       22 
24 
     | 
    
         
             
                def initialize(*args)
         
     | 
| 
         @@ -34,7 +36,7 @@ module RailsEventStoreActiveRecord 
     | 
|
| 
       34 
36 
     | 
    
         
             
                private
         
     | 
| 
       35 
37 
     | 
    
         | 
| 
       36 
38 
     | 
    
         
             
                def data_type
         
     | 
| 
       37 
     | 
    
         
            -
                  options.fetch( 
     | 
| 
      
 39 
     | 
    
         
            +
                  options.fetch("data_type")
         
     | 
| 
       38 
40 
     | 
    
         
             
                end
         
     | 
| 
       39 
41 
     | 
    
         | 
| 
       40 
42 
     | 
    
         
             
                def migration_version
         
     | 
| 
         @@ -45,4 +47,4 @@ module RailsEventStoreActiveRecord 
     | 
|
| 
       45 
47 
     | 
    
         
             
                  Time.now.strftime("%Y%m%d%H%M%S")
         
     | 
| 
       46 
48 
     | 
    
         
             
                end
         
     | 
| 
       47 
49 
     | 
    
         
             
              end
         
     | 
| 
       48 
     | 
    
         
            -
            end if defined?(Rails::Generators::Base)
         
     | 
| 
      
 50 
     | 
    
         
            +
            end if defined?(Rails::Generators::Base)
         
     | 
    
        data/lib/rails_event_store_active_record/generators/templates/create_event_store_events_template.rb
    CHANGED
    
    | 
         @@ -2,38 +2,42 @@ 
     | 
|
| 
       2 
2 
     | 
    
         | 
| 
       3 
3 
     | 
    
         
             
            class CreateEventStoreEvents < ActiveRecord::Migration<%= migration_version %>
         
     | 
| 
       4 
4 
     | 
    
         
             
              def change
         
     | 
| 
       5 
     | 
    
         
            -
                postgres = 
     | 
| 
       6 
     | 
    
         
            -
             
     | 
| 
       7 
     | 
    
         
            -
             
     | 
| 
       8 
     | 
    
         
            -
             
     | 
| 
       9 
     | 
    
         
            -
             
     | 
| 
       10 
     | 
    
         
            -
             
     | 
| 
       11 
     | 
    
         
            -
             
     | 
| 
       12 
     | 
    
         
            -
                  if postgres
         
     | 
| 
       13 
     | 
    
         
            -
                    t.references :event, null: false, type: :uuid
         
     | 
| 
       14 
     | 
    
         
            -
                  else
         
     | 
| 
       15 
     | 
    
         
            -
                    t.references :event, null: false, type: :string, limit: 36
         
     | 
| 
       16 
     | 
    
         
            -
                  end
         
     | 
| 
       17 
     | 
    
         
            -
                  if postgres
         
     | 
| 
      
 5 
     | 
    
         
            +
                postgres =
         
     | 
| 
      
 6 
     | 
    
         
            +
                  ActiveRecord::Base.connection.adapter_name == "PostgreSQL"
         
     | 
| 
      
 7 
     | 
    
         
            +
                if postgres
         
     | 
| 
      
 8 
     | 
    
         
            +
                  create_table(:event_store_events_in_streams, id: :bigserial, force: false) do |t|
         
     | 
| 
      
 9 
     | 
    
         
            +
                    t.string      :stream,      null: false
         
     | 
| 
      
 10 
     | 
    
         
            +
                    t.integer     :position,    null: true
         
     | 
| 
      
 11 
     | 
    
         
            +
                    t.references  :event,       null: false, type: :uuid
         
     | 
| 
       18 
12 
     | 
    
         
             
                    t.datetime    :created_at,  null: false
         
     | 
| 
       19 
     | 
    
         
            -
                  else
         
     | 
| 
       20 
     | 
    
         
            -
                    t.datetime    :created_at,  null: false, precision: 6
         
     | 
| 
       21 
13 
     | 
    
         
             
                  end
         
     | 
| 
       22 
     | 
    
         
            -
             
     | 
| 
       23 
     | 
    
         
            -
             
     | 
| 
       24 
     | 
    
         
            -
             
     | 
| 
       25 
     | 
    
         
            -
                add_index :event_store_events_in_streams, [:stream, :event_id], unique: true
         
     | 
| 
      
 14 
     | 
    
         
            +
                  add_index :event_store_events_in_streams, [:stream, :position], unique: true
         
     | 
| 
      
 15 
     | 
    
         
            +
                  add_index :event_store_events_in_streams, [:created_at]
         
     | 
| 
      
 16 
     | 
    
         
            +
                  add_index :event_store_events_in_streams, [:stream, :event_id], unique: true
         
     | 
| 
       26 
17 
     | 
    
         | 
| 
       27 
     | 
    
         
            -
             
     | 
| 
       28 
     | 
    
         
            -
                  create_table(:event_store_events, force: false) do |t|
         
     | 
| 
      
 18 
     | 
    
         
            +
                  create_table(:event_store_events, id: :bigserial, force: false) do |t|
         
     | 
| 
       29 
19 
     | 
    
         
             
                    t.references  :event,       null: false, type: :uuid
         
     | 
| 
       30 
20 
     | 
    
         
             
                    t.string      :event_type,  null: false
         
     | 
| 
       31 
21 
     | 
    
         
             
                    t.<%= data_type %>      :metadata
         
     | 
| 
       32 
     | 
    
         
            -
                    t.<%= data_type %>      :data, 
     | 
| 
      
 22 
     | 
    
         
            +
                    t.<%= data_type %>      :data, null: false
         
     | 
| 
       33 
23 
     | 
    
         
             
                    t.datetime    :created_at,  null: false
         
     | 
| 
       34 
24 
     | 
    
         
             
                    t.datetime    :valid_at,    null: true
         
     | 
| 
       35 
25 
     | 
    
         
             
                  end
         
     | 
| 
      
 26 
     | 
    
         
            +
                  add_index :event_store_events, :event_id, unique: true
         
     | 
| 
      
 27 
     | 
    
         
            +
                  add_index :event_store_events, :created_at
         
     | 
| 
      
 28 
     | 
    
         
            +
                  add_index :event_store_events, :valid_at
         
     | 
| 
      
 29 
     | 
    
         
            +
                  add_index :event_store_events, :event_type
         
     | 
| 
       36 
30 
     | 
    
         
             
                else
         
     | 
| 
      
 31 
     | 
    
         
            +
                  create_table(:event_store_events_in_streams, force: false) do |t|
         
     | 
| 
      
 32 
     | 
    
         
            +
                    t.string      :stream,      null: false
         
     | 
| 
      
 33 
     | 
    
         
            +
                    t.integer     :position,    null: true
         
     | 
| 
      
 34 
     | 
    
         
            +
                    t.references  :event,       null: false, type: :string, limit: 36
         
     | 
| 
      
 35 
     | 
    
         
            +
                    t.datetime    :created_at,  null: false, precision: 6
         
     | 
| 
      
 36 
     | 
    
         
            +
                  end
         
     | 
| 
      
 37 
     | 
    
         
            +
                  add_index :event_store_events_in_streams, [:stream, :position], unique: true
         
     | 
| 
      
 38 
     | 
    
         
            +
                  add_index :event_store_events_in_streams, [:created_at]
         
     | 
| 
      
 39 
     | 
    
         
            +
                  add_index :event_store_events_in_streams, [:stream, :event_id], unique: true
         
     | 
| 
      
 40 
     | 
    
         
            +
             
     | 
| 
       37 
41 
     | 
    
         
             
                  create_table(:event_store_events, force: false) do |t|
         
     | 
| 
       38 
42 
     | 
    
         
             
                    t.references  :event,       null: false, type: :string, limit: 36
         
     | 
| 
       39 
43 
     | 
    
         
             
                    t.string      :event_type,  null: false
         
     | 
| 
         @@ -42,10 +46,10 @@ class CreateEventStoreEvents < ActiveRecord::Migration<%= migration_version %> 
     | 
|
| 
       42 
46 
     | 
    
         
             
                    t.datetime    :created_at,  null: false, precision: 6
         
     | 
| 
       43 
47 
     | 
    
         
             
                    t.datetime    :valid_at,    null: true,  precision: 6
         
     | 
| 
       44 
48 
     | 
    
         
             
                  end
         
     | 
| 
      
 49 
     | 
    
         
            +
                  add_index :event_store_events, :event_id, unique: true
         
     | 
| 
      
 50 
     | 
    
         
            +
                  add_index :event_store_events, :created_at
         
     | 
| 
      
 51 
     | 
    
         
            +
                  add_index :event_store_events, :valid_at
         
     | 
| 
      
 52 
     | 
    
         
            +
                  add_index :event_store_events, :event_type
         
     | 
| 
       45 
53 
     | 
    
         
             
                end
         
     | 
| 
       46 
     | 
    
         
            -
                add_index :event_store_events, :event_id, unique: true
         
     | 
| 
       47 
     | 
    
         
            -
                add_index :event_store_events, :created_at
         
     | 
| 
       48 
     | 
    
         
            -
                add_index :event_store_events, :valid_at
         
     | 
| 
       49 
     | 
    
         
            -
                add_index :event_store_events, :event_type
         
     | 
| 
       50 
54 
     | 
    
         
             
              end
         
     | 
| 
       51 
55 
     | 
    
         
             
            end
         
     | 
| 
         @@ -2,41 +2,37 @@ 
     | 
|
| 
       2 
2 
     | 
    
         | 
| 
       3 
3 
     | 
    
         
             
            module RailsEventStoreActiveRecord
         
     | 
| 
       4 
4 
     | 
    
         
             
              class IndexViolationDetector
         
     | 
| 
       5 
     | 
    
         
            -
             
     | 
| 
       6 
5 
     | 
    
         
             
                def initialize(event_store_events, event_store_events_in_streams)
         
     | 
| 
       7 
     | 
    
         
            -
                  @postgres_pkey_error 
     | 
| 
      
 6 
     | 
    
         
            +
                  @postgres_pkey_error = "Key (event_id)".freeze
         
     | 
| 
       8 
7 
     | 
    
         
             
                  @postgres_index_error = "Key (stream, event_id)".freeze
         
     | 
| 
       9 
     | 
    
         
            -
                  @mysql5_pkey_error 
     | 
| 
       10 
     | 
    
         
            -
                  @mysql8_pkey_error 
     | 
| 
       11 
     | 
    
         
            -
                  @mysql5_index_error 
     | 
| 
       12 
     | 
    
         
            -
                  @mysql8_index_error 
     | 
| 
       13 
     | 
    
         
            -
             
     | 
| 
       14 
     | 
    
         
            -
             
     | 
| 
      
 8 
     | 
    
         
            +
                  @mysql5_pkey_error = "for key 'index_#{event_store_events}_on_event_id'".freeze
         
     | 
| 
      
 9 
     | 
    
         
            +
                  @mysql8_pkey_error = "for key '#{event_store_events}.index_#{event_store_events}_on_event_id'".freeze
         
     | 
| 
      
 10 
     | 
    
         
            +
                  @mysql5_index_error = "for key 'index_#{event_store_events_in_streams}_on_stream_and_event_id'".freeze
         
     | 
| 
      
 11 
     | 
    
         
            +
                  @mysql8_index_error =
         
     | 
| 
      
 12 
     | 
    
         
            +
                    "for key '#{event_store_events_in_streams}.index_#{event_store_events_in_streams}_on_stream_and_event_id'"
         
     | 
| 
      
 13 
     | 
    
         
            +
                      .freeze
         
     | 
| 
      
 14 
     | 
    
         
            +
                  @sqlite3_pkey_error = "constraint failed: #{event_store_events}.event_id".freeze
         
     | 
| 
      
 15 
     | 
    
         
            +
                  @sqlite3_index_error =
         
     | 
| 
      
 16 
     | 
    
         
            +
                    "constraint failed: #{event_store_events_in_streams}.stream, #{event_store_events_in_streams}.event_id".freeze
         
     | 
| 
       15 
17 
     | 
    
         
             
                end
         
     | 
| 
       16 
18 
     | 
    
         | 
| 
       17 
19 
     | 
    
         
             
                def detect(message)
         
     | 
| 
       18 
     | 
    
         
            -
                  detect_postgres(message) ||
         
     | 
| 
       19 
     | 
    
         
            -
                    detect_mysql(message)  ||
         
     | 
| 
       20 
     | 
    
         
            -
                    detect_sqlite(message)
         
     | 
| 
      
 20 
     | 
    
         
            +
                  detect_postgres(message) || detect_mysql(message) || detect_sqlite(message)
         
     | 
| 
       21 
21 
     | 
    
         
             
                end
         
     | 
| 
       22 
22 
     | 
    
         | 
| 
       23 
23 
     | 
    
         
             
                private
         
     | 
| 
       24 
24 
     | 
    
         | 
| 
       25 
25 
     | 
    
         
             
                def detect_postgres(message)
         
     | 
| 
       26 
     | 
    
         
            -
                  message.include?(@postgres_pkey_error) ||
         
     | 
| 
       27 
     | 
    
         
            -
                    message.include?(@postgres_index_error)
         
     | 
| 
      
 26 
     | 
    
         
            +
                  message.include?(@postgres_pkey_error) || message.include?(@postgres_index_error)
         
     | 
| 
       28 
27 
     | 
    
         
             
                end
         
     | 
| 
       29 
28 
     | 
    
         | 
| 
       30 
29 
     | 
    
         
             
                def detect_mysql(message)
         
     | 
| 
       31 
     | 
    
         
            -
                  message.include?(@mysql5_pkey_error) 
     | 
| 
       32 
     | 
    
         
            -
                    message.include?(@ 
     | 
| 
       33 
     | 
    
         
            -
                    message.include?(@mysql5_index_error) ||
         
     | 
| 
       34 
     | 
    
         
            -
                    message.include?(@mysql8_index_error)
         
     | 
| 
      
 30 
     | 
    
         
            +
                  message.include?(@mysql5_pkey_error) || message.include?(@mysql8_pkey_error) ||
         
     | 
| 
      
 31 
     | 
    
         
            +
                    message.include?(@mysql5_index_error) || message.include?(@mysql8_index_error)
         
     | 
| 
       35 
32 
     | 
    
         
             
                end
         
     | 
| 
       36 
33 
     | 
    
         | 
| 
       37 
34 
     | 
    
         
             
                def detect_sqlite(message)
         
     | 
| 
       38 
     | 
    
         
            -
                  message.include?(@sqlite3_pkey_error) ||
         
     | 
| 
       39 
     | 
    
         
            -
                    message.include?(@sqlite3_index_error)
         
     | 
| 
      
 35 
     | 
    
         
            +
                  message.include?(@sqlite3_pkey_error) || message.include?(@sqlite3_index_error)
         
     | 
| 
       40 
36 
     | 
    
         
             
                end
         
     | 
| 
       41 
37 
     | 
    
         
             
              end
         
     | 
| 
       42 
38 
     | 
    
         | 
| 
         @@ -1,20 +1,13 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            # frozen_string_literal: true
         
     | 
| 
       2 
2 
     | 
    
         | 
| 
       3 
     | 
    
         
            -
            require 'activerecord-import'
         
     | 
| 
       4 
     | 
    
         
            -
             
     | 
| 
       5 
3 
     | 
    
         
             
            module RailsEventStoreActiveRecord
         
     | 
| 
       6 
4 
     | 
    
         
             
              class PgLinearizedEventRepository < EventRepository
         
     | 
| 
       7 
     | 
    
         
            -
             
     | 
| 
       8 
5 
     | 
    
         
             
                def start_transaction(&proc)
         
     | 
| 
       9 
6 
     | 
    
         
             
                  ActiveRecord::Base.transaction(requires_new: true) do
         
     | 
| 
       10 
     | 
    
         
            -
                    ActiveRecord::Base
         
     | 
| 
       11 
     | 
    
         
            -
                      .connection
         
     | 
| 
       12 
     | 
    
         
            -
                      .execute("SELECT pg_advisory_xact_lock(1845240511599988039) as l")
         
     | 
| 
       13 
     | 
    
         
            -
                      .each{}
         
     | 
| 
      
 7 
     | 
    
         
            +
                    ActiveRecord::Base.connection.execute("SELECT pg_advisory_xact_lock(1845240511599988039) as l").each {}
         
     | 
| 
       14 
8 
     | 
    
         | 
| 
       15 
9 
     | 
    
         
             
                    proc.call
         
     | 
| 
       16 
10 
     | 
    
         
             
                  end
         
     | 
| 
       17 
11 
     | 
    
         
             
                end
         
     | 
| 
       18 
     | 
    
         
            -
             
     | 
| 
       19 
12 
     | 
    
         
             
              end
         
     | 
| 
       20 
13 
     | 
    
         
             
            end
         
     | 
| 
         @@ -3,34 +3,34 @@ 
     | 
|
| 
       3 
3 
     | 
    
         
             
            module RailsEventStoreActiveRecord
         
     | 
| 
       4 
4 
     | 
    
         
             
              class WithAbstractBaseClass
         
     | 
| 
       5 
5 
     | 
    
         
             
                def initialize(base_klass)
         
     | 
| 
       6 
     | 
    
         
            -
                   
     | 
| 
       7 
     | 
    
         
            -
                    "#{base_klass} must be an abstract class that inherits from ActiveRecord::Base"
         
     | 
| 
       8 
     | 
    
         
            -
                   
     | 
| 
      
 6 
     | 
    
         
            +
                  unless base_klass < ActiveRecord::Base && base_klass.abstract_class?
         
     | 
| 
      
 7 
     | 
    
         
            +
                    raise ArgumentError.new("#{base_klass} must be an abstract class that inherits from ActiveRecord::Base")
         
     | 
| 
      
 8 
     | 
    
         
            +
                  end
         
     | 
| 
       9 
9 
     | 
    
         
             
                  @base_klass = base_klass
         
     | 
| 
       10 
10 
     | 
    
         
             
                end
         
     | 
| 
       11 
11 
     | 
    
         | 
| 
       12 
12 
     | 
    
         
             
                def call(instance_id: SecureRandom.hex)
         
     | 
| 
       13 
     | 
    
         
            -
                  [
         
     | 
| 
       14 
     | 
    
         
            -
                    build_event_klass(instance_id),
         
     | 
| 
       15 
     | 
    
         
            -
                    build_stream_klass(instance_id),
         
     | 
| 
       16 
     | 
    
         
            -
                  ]
         
     | 
| 
      
 13 
     | 
    
         
            +
                  [build_event_klass(instance_id), build_stream_klass(instance_id)]
         
     | 
| 
       17 
14 
     | 
    
         
             
                end
         
     | 
| 
       18 
15 
     | 
    
         | 
| 
       19 
16 
     | 
    
         
             
                private
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
       20 
18 
     | 
    
         
             
                def build_event_klass(instance_id)
         
     | 
| 
       21 
     | 
    
         
            -
                  Object.const_set( 
     | 
| 
      
 19 
     | 
    
         
            +
                  Object.const_set(
         
     | 
| 
      
 20 
     | 
    
         
            +
                    "Event_#{instance_id}",
         
     | 
| 
       22 
21 
     | 
    
         
             
                    Class.new(@base_klass) do
         
     | 
| 
       23 
22 
     | 
    
         
             
                      self.primary_key = :id
         
     | 
| 
       24 
     | 
    
         
            -
                      self.table_name 
     | 
| 
      
 23 
     | 
    
         
            +
                      self.table_name = "event_store_events"
         
     | 
| 
       25 
24 
     | 
    
         
             
                    end
         
     | 
| 
       26 
25 
     | 
    
         
             
                  )
         
     | 
| 
       27 
26 
     | 
    
         
             
                end
         
     | 
| 
       28 
27 
     | 
    
         | 
| 
       29 
28 
     | 
    
         
             
                def build_stream_klass(instance_id)
         
     | 
| 
       30 
     | 
    
         
            -
                  Object.const_set( 
     | 
| 
      
 29 
     | 
    
         
            +
                  Object.const_set(
         
     | 
| 
      
 30 
     | 
    
         
            +
                    "EventInStream_#{instance_id}",
         
     | 
| 
       31 
31 
     | 
    
         
             
                    Class.new(@base_klass) do
         
     | 
| 
       32 
32 
     | 
    
         
             
                      self.primary_key = :id
         
     | 
| 
       33 
     | 
    
         
            -
                      self.table_name =  
     | 
| 
      
 33 
     | 
    
         
            +
                      self.table_name = "event_store_events_in_streams"
         
     | 
| 
       34 
34 
     | 
    
         
             
                      belongs_to :event, primary_key: :event_id, class_name: "Event_#{instance_id}"
         
     | 
| 
       35 
35 
     | 
    
         
             
                    end
         
     | 
| 
       36 
36 
     | 
    
         
             
                  )
         
     | 
| 
         @@ -1,12 +1,12 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            # frozen_string_literal: true
         
     | 
| 
       2 
2 
     | 
    
         | 
| 
       3 
     | 
    
         
            -
             
     | 
| 
       4 
     | 
    
         
            -
             
     | 
| 
       5 
     | 
    
         
            -
             
     | 
| 
       6 
     | 
    
         
            -
             
     | 
| 
       7 
     | 
    
         
            -
             
     | 
| 
       8 
     | 
    
         
            -
             
     | 
| 
       9 
     | 
    
         
            -
             
     | 
| 
       10 
     | 
    
         
            -
             
     | 
| 
       11 
     | 
    
         
            -
             
     | 
| 
       12 
     | 
    
         
            -
             
     | 
| 
      
 3 
     | 
    
         
            +
            require_relative "rails_event_store_active_record/generators/migration_generator"
         
     | 
| 
      
 4 
     | 
    
         
            +
            require_relative "rails_event_store_active_record/event"
         
     | 
| 
      
 5 
     | 
    
         
            +
            require_relative "rails_event_store_active_record/with_default_models"
         
     | 
| 
      
 6 
     | 
    
         
            +
            require_relative "rails_event_store_active_record/with_abstract_base_class"
         
     | 
| 
      
 7 
     | 
    
         
            +
            require_relative "rails_event_store_active_record/event_repository"
         
     | 
| 
      
 8 
     | 
    
         
            +
            require_relative "rails_event_store_active_record/batch_enumerator"
         
     | 
| 
      
 9 
     | 
    
         
            +
            require_relative "rails_event_store_active_record/event_repository_reader"
         
     | 
| 
      
 10 
     | 
    
         
            +
            require_relative "rails_event_store_active_record/index_violation_detector"
         
     | 
| 
      
 11 
     | 
    
         
            +
            require_relative "rails_event_store_active_record/pg_linearized_event_repository"
         
     | 
| 
      
 12 
     | 
    
         
            +
            require_relative "rails_event_store_active_record/version"
         
     | 
    
        metadata
    CHANGED
    
    | 
         @@ -1,14 +1,14 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            --- !ruby/object:Gem::Specification
         
     | 
| 
       2 
2 
     | 
    
         
             
            name: rails_event_store_active_record
         
     | 
| 
       3 
3 
     | 
    
         
             
            version: !ruby/object:Gem::Version
         
     | 
| 
       4 
     | 
    
         
            -
              version: 2. 
     | 
| 
      
 4 
     | 
    
         
            +
              version: 2.4.0
         
     | 
| 
       5 
5 
     | 
    
         
             
            platform: ruby
         
     | 
| 
       6 
6 
     | 
    
         
             
            authors:
         
     | 
| 
       7 
7 
     | 
    
         
             
            - Arkency
         
     | 
| 
       8 
8 
     | 
    
         
             
            autorequire:
         
     | 
| 
       9 
9 
     | 
    
         
             
            bindir: bin
         
     | 
| 
       10 
10 
     | 
    
         
             
            cert_chain: []
         
     | 
| 
       11 
     | 
    
         
            -
            date:  
     | 
| 
      
 11 
     | 
    
         
            +
            date: 2022-05-27 00:00:00.000000000 Z
         
     | 
| 
       12 
12 
     | 
    
         
             
            dependencies:
         
     | 
| 
       13 
13 
     | 
    
         
             
            - !ruby/object:Gem::Dependency
         
     | 
| 
       14 
14 
     | 
    
         
             
              name: ruby_event_store
         
     | 
| 
         @@ -16,42 +16,28 @@ dependencies: 
     | 
|
| 
       16 
16 
     | 
    
         
             
                requirements:
         
     | 
| 
       17 
17 
     | 
    
         
             
                - - '='
         
     | 
| 
       18 
18 
     | 
    
         
             
                  - !ruby/object:Gem::Version
         
     | 
| 
       19 
     | 
    
         
            -
                    version: 2. 
     | 
| 
      
 19 
     | 
    
         
            +
                    version: 2.4.0
         
     | 
| 
       20 
20 
     | 
    
         
             
              type: :runtime
         
     | 
| 
       21 
21 
     | 
    
         
             
              prerelease: false
         
     | 
| 
       22 
22 
     | 
    
         
             
              version_requirements: !ruby/object:Gem::Requirement
         
     | 
| 
       23 
23 
     | 
    
         
             
                requirements:
         
     | 
| 
       24 
24 
     | 
    
         
             
                - - '='
         
     | 
| 
       25 
25 
     | 
    
         
             
                  - !ruby/object:Gem::Version
         
     | 
| 
       26 
     | 
    
         
            -
                    version: 2. 
     | 
| 
      
 26 
     | 
    
         
            +
                    version: 2.4.0
         
     | 
| 
       27 
27 
     | 
    
         
             
            - !ruby/object:Gem::Dependency
         
     | 
| 
       28 
28 
     | 
    
         
             
              name: activerecord
         
     | 
| 
       29 
29 
     | 
    
         
             
              requirement: !ruby/object:Gem::Requirement
         
     | 
| 
       30 
30 
     | 
    
         
             
                requirements:
         
     | 
| 
       31 
31 
     | 
    
         
             
                - - ">="
         
     | 
| 
       32 
32 
     | 
    
         
             
                  - !ruby/object:Gem::Version
         
     | 
| 
       33 
     | 
    
         
            -
                    version: ' 
     | 
| 
      
 33 
     | 
    
         
            +
                    version: '6.0'
         
     | 
| 
       34 
34 
     | 
    
         
             
              type: :runtime
         
     | 
| 
       35 
35 
     | 
    
         
             
              prerelease: false
         
     | 
| 
       36 
36 
     | 
    
         
             
              version_requirements: !ruby/object:Gem::Requirement
         
     | 
| 
       37 
37 
     | 
    
         
             
                requirements:
         
     | 
| 
       38 
38 
     | 
    
         
             
                - - ">="
         
     | 
| 
       39 
39 
     | 
    
         
             
                  - !ruby/object:Gem::Version
         
     | 
| 
       40 
     | 
    
         
            -
                    version: ' 
     | 
| 
       41 
     | 
    
         
            -
            - !ruby/object:Gem::Dependency
         
     | 
| 
       42 
     | 
    
         
            -
              name: activerecord-import
         
     | 
| 
       43 
     | 
    
         
            -
              requirement: !ruby/object:Gem::Requirement
         
     | 
| 
       44 
     | 
    
         
            -
                requirements:
         
     | 
| 
       45 
     | 
    
         
            -
                - - ">="
         
     | 
| 
       46 
     | 
    
         
            -
                  - !ruby/object:Gem::Version
         
     | 
| 
       47 
     | 
    
         
            -
                    version: 1.0.2
         
     | 
| 
       48 
     | 
    
         
            -
              type: :runtime
         
     | 
| 
       49 
     | 
    
         
            -
              prerelease: false
         
     | 
| 
       50 
     | 
    
         
            -
              version_requirements: !ruby/object:Gem::Requirement
         
     | 
| 
       51 
     | 
    
         
            -
                requirements:
         
     | 
| 
       52 
     | 
    
         
            -
                - - ">="
         
     | 
| 
       53 
     | 
    
         
            -
                  - !ruby/object:Gem::Version
         
     | 
| 
       54 
     | 
    
         
            -
                    version: 1.0.2
         
     | 
| 
      
 40 
     | 
    
         
            +
                    version: '6.0'
         
     | 
| 
       55 
41 
     | 
    
         
             
            description: |
         
     | 
| 
       56 
42 
     | 
    
         
             
              Persistent event repository implementation for RubyEventStore based on ActiveRecord. Ships with database schema
         
     | 
| 
       57 
43 
     | 
    
         
             
              and migrations suitable for PostgreSQL, MySQL ans SQLite database engines.
         
     | 
| 
         @@ -85,6 +71,7 @@ metadata: 
     | 
|
| 
       85 
71 
     | 
    
         
             
              changelog_uri: https://github.com/RailsEventStore/rails_event_store/releases
         
     | 
| 
       86 
72 
     | 
    
         
             
              source_code_uri: https://github.com/RailsEventStore/rails_event_store
         
     | 
| 
       87 
73 
     | 
    
         
             
              bug_tracker_uri: https://github.com/RailsEventStore/rails_event_store/issues
         
     | 
| 
      
 74 
     | 
    
         
            +
              rubygems_mfa_required: 'true'
         
     | 
| 
       88 
75 
     | 
    
         
             
            post_install_message:
         
     | 
| 
       89 
76 
     | 
    
         
             
            rdoc_options: []
         
     | 
| 
       90 
77 
     | 
    
         
             
            require_paths:
         
     | 
| 
         @@ -93,14 +80,14 @@ required_ruby_version: !ruby/object:Gem::Requirement 
     | 
|
| 
       93 
80 
     | 
    
         
             
              requirements:
         
     | 
| 
       94 
81 
     | 
    
         
             
              - - ">="
         
     | 
| 
       95 
82 
     | 
    
         
             
                - !ruby/object:Gem::Version
         
     | 
| 
       96 
     | 
    
         
            -
                  version: '2. 
     | 
| 
      
 83 
     | 
    
         
            +
                  version: '2.7'
         
     | 
| 
       97 
84 
     | 
    
         
             
            required_rubygems_version: !ruby/object:Gem::Requirement
         
     | 
| 
       98 
85 
     | 
    
         
             
              requirements:
         
     | 
| 
       99 
86 
     | 
    
         
             
              - - ">="
         
     | 
| 
       100 
87 
     | 
    
         
             
                - !ruby/object:Gem::Version
         
     | 
| 
       101 
88 
     | 
    
         
             
                  version: '0'
         
     | 
| 
       102 
89 
     | 
    
         
             
            requirements: []
         
     | 
| 
       103 
     | 
    
         
            -
            rubygems_version: 3. 
     | 
| 
      
 90 
     | 
    
         
            +
            rubygems_version: 3.3.7
         
     | 
| 
       104 
91 
     | 
    
         
             
            signing_key:
         
     | 
| 
       105 
92 
     | 
    
         
             
            specification_version: 4
         
     | 
| 
       106 
93 
     | 
    
         
             
            summary: Persistent event repository implementation for RubyEventStore based on ActiveRecord
         
     |