@pawelpacana pawelpacana released this Nov 23, 2018 · 102 commits to master since this release

Assets 2

RailsEventStore

  • Add: New read API to filter read events by type event_store.read.of_type [#472]

     event_store = RailsEventStore::Client.new
     TweetPosted = Class.new(RubyEventStore::Event)
     TweetRetweeted = Class.new(RubyEventStore::Event)
     TweetLiked = Class.new(RubyEventStore::Event)
     event_store.publish(TweetPosted.new(event_id: '54994b0e-4fe3-4d58-8ffe-16755fcbc635', data: { message: 'Hello from @RailsEventStore!' }))
     event_store.publish(TweetRetweeted.new(event_id: '3d67e05d-04c6-4771-bdcc-d22d385390cb', data: { ... }))
    
    
     event_store.read.of_type([TweetPosted]).to_a
     # => [#<TweetPosted:0x00007fce3cab1a00 @event_id="54994b0e-4fe3-4d58-8ffe-16755fcbc635", @metadata=#<RubyEventStore::Metadata:0x00007fce3cab19b0 @h={:timestamp=>2018-10-12 17:50:27 UTC}>, @data={:message=>"Hello from @RailsEventStore!"}>]
    
     event_store.read.of_type([TweetLiked]).to_a
     # => []
  • Change: RailsEventStore::Event#initialize no longer calls to_h on data: argument. Default value for this argument stays effectively the same (which is {}). One now has an option to pass struct or any other object as data, provided your configured mapper knows how to handle it for serialization [#395, #480]

  • Add: Bring back RailsEventStore::Browser. This time not as a separate gem, rather a thin wrapper over RubyEventStore::Browser. It is no longer needed with rails_event_store to add browser as an explicit dependency. As a bonus RailsEventStore::Browser already has event_store_locator: pre-configured to typical Rails.configuration.event_store [#497]

    The whole process of mounting Browser in Rails is as simple as following:

    Rails.application.routes.draw do
      mount RailsEventStore::Browser => '/res' if Rails.env.development?
    end

RubyEventStore

  • Add: New read API to filter read events by type event_store.read.of_type [#472]

     event_store = RailsEventStore::Client.new
     TweetPosted = Class.new(RubyEventStore::Event)
     TweetRetweeted = Class.new(RubyEventStore::Event)
     TweetLiked = Class.new(RubyEventStore::Event)
     event_store.publish(TweetPosted.new(event_id: '54994b0e-4fe3-4d58-8ffe-16755fcbc635', data: { message: 'Hello from @RailsEventStore!' }))
     event_store.publish(TweetRetweeted.new(event_id: '3d67e05d-04c6-4771-bdcc-d22d385390cb', data: { ... }))
    
    
     event_store.read.of_type([TweetPosted]).to_a
     # => [#<TweetPosted:0x00007fce3cab1a00 @event_id="54994b0e-4fe3-4d58-8ffe-16755fcbc635", @metadata=#<RubyEventStore::Metadata:0x00007fce3cab19b0 @h={:timestamp=>2018-10-12 17:50:27 UTC}>, @data={:message=>"Hello from @RailsEventStore!"}>]
    
     event_store.read.of_type([TweetLiked]).to_a
     # => []
  • Fix: Do not compare object instances of event id while looking for streams of event [#492]

  • Fix: read.events([]) returning whole dataset of stored events [#498]

  • Change: RubyEventStore::Event#initialize no longer calls to_h on data: argument. Default value for this argument stays effectively the same (which is {}). One now has an option to pass struct or any other object as data, provided your configured mapper knows how to handle it for serialization [#395, #480]

  • Add: Explicit RubyEventStore::ProtobufEncodingFailed raised when event's data is not serializable by RubyEventStore::Mappers::Protobuf [#481]

  • Fix: RubyEventStore::Mappers::Default#serialized_record_to_event now symbolizes metadata keys. This helps when your serializer cannot distinguish symbols from strings (i.e. when you choose JSON as a serializer) [#367, #489]

    When using RubyEventStore::Mappers::Default.new(serializer: JSON) it is advisable to make following or similar adjustment to your base Event class. That way you'll shield yourself from JSON turning symbols intro strings:

    class MyEvent < RailsEventStore::Event
      def data
        ActiveSupport::HashWithIndifferentAccess.new(super)
      end
    end
    
    OrderPlaced = Class.new(MyEvent)

    More on configuring a different serializer section.

RailsEventStoreActiveRecord

  • Add: Support for filtering by event type [#472]

  • Add: New migration generator to add an index on event_type attribute. Strongly recommended to apply if you plan to use filtering by event types — otherwise performance when using event_store.read.of_type(...) might be degraded. Added in default schema creation generator for new deployments. [#472]

    Running migration:

    rails g rails_event_store_active_record:index_by_event_type
    rails db:migrate
    

    Feel free to inspect and change generated migration. Make sure to check if your RDBMS can run this migration online and whether that meets your operational requirements.
    https://dev.mysql.com/doc/refman/5.7/en/innodb-online-ddl-operations.html#online-ddl-index-operations

  • Add: New migration generator to add a limit on event_id attribute in event_store_events_in_streams table. Applicable for MySQL and Sqlite databases. This migration is skipped on PostgreSQL. Feel free to skip this migration if it's too problematic to apply on existing data. Added in default schema creation generator for new deployments. [#479]

    Running migration:

    rails g rails_event_store_active_record:limit_for_event_id
    rails db:migrate
    

    Feel free to inspect and change generated migration. Make sure to check if your RDBMS can run this migration online and whether that meets your operational requirements.
    https://dev.mysql.com/doc/refman/5.7/en/innodb-online-ddl-operations.html#online-ddl-column-operations

  • Add: to_a implementation for read specification. Allows to avoid commonly used event_store.read.each.to_a by just using event_store.read.to_a. Also added to_a & first methods to BatchEnumerator. Closes #496. [#499]

AggregateRoot

  • no changes

RailsEventStore::RSpec

  • no changes

BoundedContext

  • no changes

RubyEventStore::Browser

  • Fix: Ensure Browser works with non-default metadata serialization [#491]

  • Change: Provide default arguments to RubyEventStore::Browser::App.for for less required setup in typical use case [#483]

    Now only event_store_locator: is required when mounting Browser inside existing app.

    require 'ruby_event_store/browser/app'
    
    Rails.application.routes.draw do
      mount RubyEventStore::Browser::App.for(
        event_store_locator: -> { Rails.configuration.event_store },
      ) => '/res' if Rails.env.development?
    end

RubyEventStore::ROM

  • Support for filtering by event type [#472]

RailsEventStoreActiveRecord::Legacy

  • Support for filtering by event type [#472]