sequent 2.1.0 → 3.0.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.
Files changed (57) hide show
  1. checksums.yaml +4 -4
  2. data/bin/sequent +65 -0
  3. data/db/sequent_schema.rb +9 -8
  4. data/lib/sequent.rb +3 -0
  5. data/lib/sequent/configuration.rb +67 -0
  6. data/lib/sequent/core/aggregate_repository.rb +1 -1
  7. data/lib/sequent/core/core.rb +2 -2
  8. data/lib/sequent/core/event_store.rb +2 -2
  9. data/lib/sequent/core/helpers/attribute_support.rb +3 -0
  10. data/lib/sequent/core/helpers/self_applier.rb +1 -1
  11. data/lib/sequent/core/{record_sessions/active_record_session.rb → persistors/active_record_persistor.rb} +21 -19
  12. data/lib/sequent/core/persistors/persistor.rb +84 -0
  13. data/lib/sequent/core/persistors/persistors.rb +3 -0
  14. data/lib/sequent/core/{record_sessions/replay_events_session.rb → persistors/replay_optimized_postgres_persistor.rb} +16 -7
  15. data/lib/sequent/core/projector.rb +96 -0
  16. data/lib/sequent/generator.rb +2 -0
  17. data/lib/sequent/generator/aggregate.rb +71 -0
  18. data/lib/sequent/generator/project.rb +61 -0
  19. data/lib/sequent/generator/template_aggregate/template_aggregate.rb +4 -0
  20. data/lib/sequent/generator/template_aggregate/template_aggregate/commands.rb +2 -0
  21. data/lib/sequent/generator/template_aggregate/template_aggregate/events.rb +2 -0
  22. data/lib/sequent/generator/template_aggregate/template_aggregate/template_aggregate.rb +9 -0
  23. data/lib/sequent/generator/template_aggregate/template_aggregate/template_aggregate_command_handler.rb +5 -0
  24. data/lib/sequent/generator/template_project/Gemfile +11 -0
  25. data/lib/sequent/generator/template_project/Gemfile.lock +72 -0
  26. data/lib/sequent/generator/template_project/Rakefile +12 -0
  27. data/lib/sequent/generator/template_project/app/projectors/post_projector.rb +22 -0
  28. data/lib/sequent/generator/template_project/app/records/post_record.rb +2 -0
  29. data/lib/sequent/generator/template_project/config/initializers/sequent.rb +13 -0
  30. data/lib/sequent/generator/template_project/db/database.yml +17 -0
  31. data/lib/sequent/generator/template_project/db/migrations.rb +17 -0
  32. data/lib/sequent/generator/template_project/db/sequent_schema.rb +51 -0
  33. data/lib/sequent/generator/template_project/db/tables/post_records.sql +10 -0
  34. data/lib/sequent/generator/template_project/lib/post.rb +4 -0
  35. data/lib/sequent/generator/template_project/lib/post/commands.rb +4 -0
  36. data/lib/sequent/generator/template_project/lib/post/events.rb +14 -0
  37. data/lib/sequent/generator/template_project/lib/post/post.rb +24 -0
  38. data/lib/sequent/generator/template_project/lib/post/post_command_handler.rb +5 -0
  39. data/lib/sequent/generator/template_project/my_app.rb +11 -0
  40. data/lib/sequent/generator/template_project/spec/app/projectors/post_projector_spec.rb +32 -0
  41. data/lib/sequent/generator/template_project/spec/lib/post/post_command_handler_spec.rb +20 -0
  42. data/lib/sequent/generator/template_project/spec/spec_helper.rb +29 -0
  43. data/lib/sequent/migrations/migrate_events.rb +1 -0
  44. data/lib/sequent/migrations/migrations.rb +2 -0
  45. data/lib/sequent/migrations/projectors.rb +18 -0
  46. data/lib/sequent/migrations/view_schema.rb +364 -0
  47. data/lib/sequent/rake/migration_tasks.rb +109 -0
  48. data/lib/sequent/rake/tasks.rb +16 -0
  49. data/lib/sequent/sequent.rb +53 -13
  50. data/lib/sequent/support/database.rb +53 -8
  51. data/lib/sequent/util/printer.rb +16 -0
  52. data/lib/sequent/util/timer.rb +14 -0
  53. data/lib/sequent/util/util.rb +2 -0
  54. data/lib/version.rb +1 -1
  55. metadata +67 -14
  56. data/lib/sequent/core/base_event_handler.rb +0 -54
  57. data/lib/sequent/core/record_sessions/record_sessions.rb +0 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 73d2ee9247b64d69617de99ffed129de86385e4a58f463b52d5558126ccf89ba
4
- data.tar.gz: 32b61b477f9a7ff2d0df8b93a7a704705a20b661cdeab3b9388431e4ec4b9d8d
3
+ metadata.gz: ee34fdc286ef0c550e0ccd50b64f1e726457c3e58e656797e84cb36bd9e36aa0
4
+ data.tar.gz: 77546ab25b533fc77ce08cfee7252df089362d533b52d2c09e885298e197c737
5
5
  SHA512:
6
- metadata.gz: 784e843cfc6a86120b9f48779fad3104d3504fd7d472ab925a19f0de897fd2b0f745d1fb4e8c77bcecbb254976e0148443d18bed52dabd8f9400cf1551c451d3
7
- data.tar.gz: 9f027d9bb65d643ecb5cf2b37c854890d4c3b3bba840373088e3a1b35db92de0d7f22bc76ebc92910d076e6ed102aba9d20fe96f5195e0e9ed3f36bd5a53ee4c
6
+ metadata.gz: 91d3d4c9e946d75488adf4e3b86fb20c99c90f4c324d3d29f276518357f5ec8ba2db12707f48ecf0a577eb15582dce38c01fd1a6885501faea1e1a384c967ccf
7
+ data.tar.gz: 007c283a04b967879769152a4e0b2e5f84b4571f64de751621e5337d75b39e17473be44f8a61358e3fcbfe8e73d9bec64c3d83b7d8d0823ebdf2e5740cb3f22c
data/bin/sequent ADDED
@@ -0,0 +1,65 @@
1
+ #!/usr/bin/env ruby
2
+ require_relative '../lib/sequent/generator'
3
+
4
+ def new_project(args)
5
+ name, _ = args
6
+ abort('Please specify a directory name. i.e. `sequent new myapp`') if name.empty?
7
+
8
+ Sequent::Generator::Project.new(name).execute
9
+ puts <<~NEXTSTEPS
10
+
11
+ Success!
12
+
13
+ Your brand spanking new sequent app is waiting for you in:
14
+ #{File.expand_path(name, __dir__)}
15
+
16
+ To finish setting up your app:
17
+ cd #{name}
18
+ bundle install
19
+ bundle exec rake sequent:db:create
20
+ bundle exec rake sequent:migrate:online
21
+ bundle exec rake sequent:migrate:offline
22
+
23
+ Run the example specs:
24
+ RACK_ENV=test bundle exec rake sequent:db:create
25
+ bundle exec rspec spec
26
+
27
+ To generate new aggregates use:
28
+ sequent generate <aggregate_name>. e.g. sequent generate address
29
+
30
+ For more information see:
31
+ sequent.io
32
+
33
+ Happy coding!
34
+
35
+ NEXTSTEPS
36
+ end
37
+
38
+ def generate(args)
39
+ entity, _ = args
40
+ abort('Please specify a command. i.e. `sequent g aggregate user`') if entity.empty?
41
+
42
+ case entity
43
+ when 'aggregate'
44
+ _, aggregate_name = args
45
+ abort('Please specify a aggregate name. i.e. `sequent g aggregate user`') if !aggregate_name || aggregate_name.empty?
46
+
47
+ Sequent::Generator::Aggregate.new(aggregate_name).execute
48
+ puts "#{aggregate_name} aggregate has been generated"
49
+ else
50
+ abort("Unknown argument #{entity} for `generate`. Try `sequent g aggregate user`")
51
+ end
52
+ end
53
+
54
+ command = ARGV[0].to_s.strip
55
+ abort('Please specify a command. i.e. `sequent new myapp`') if command.empty?
56
+ args = ARGV[1..10].map(&:to_s).map(&:strip)
57
+
58
+ case command
59
+ when 'new'
60
+ new_project(args)
61
+ when 'generate', 'g'
62
+ generate(args)
63
+ else
64
+ abort("Unknown command #{command}. Try `sequent new myapp`")
65
+ end
data/db/sequent_schema.rb CHANGED
@@ -10,14 +10,6 @@ ActiveRecord::Schema.define do
10
10
  t.integer "stream_record_id", :null => false
11
11
  end
12
12
 
13
- create_table "command_records", :force => true do |t|
14
- t.string "user_id"
15
- t.string "aggregate_id"
16
- t.string "command_type", :null => false
17
- t.text "command_json", :null => false
18
- t.datetime "created_at", :null => false
19
- end
20
-
21
13
  execute %Q{
22
14
  CREATE UNIQUE INDEX unique_event_per_aggregate ON event_records (
23
15
  aggregate_id,
@@ -28,10 +20,19 @@ CREATE UNIQUE INDEX unique_event_per_aggregate ON event_records (
28
20
  execute %Q{
29
21
  CREATE INDEX snapshot_events ON event_records (aggregate_id, sequence_number DESC) WHERE event_type = 'Sequent::Core::SnapshotEvent'
30
22
  }
23
+
31
24
  add_index "event_records", ["command_record_id"], :name => "index_event_records_on_command_record_id"
32
25
  add_index "event_records", ["event_type"], :name => "index_event_records_on_event_type"
33
26
  add_index "event_records", ["created_at"], :name => "index_event_records_on_created_at"
34
27
 
28
+ create_table "command_records", :force => true do |t|
29
+ t.string "user_id"
30
+ t.string "aggregate_id"
31
+ t.string "command_type", :null => false
32
+ t.text "command_json", :null => false
33
+ t.datetime "created_at", :null => false
34
+ end
35
+
35
36
  create_table "stream_records", :force => true do |t|
36
37
  t.datetime "created_at", :null => false
37
38
  t.string "aggregate_type", :null => false
data/lib/sequent.rb CHANGED
@@ -1 +1,4 @@
1
1
  require_relative 'sequent/sequent'
2
+ require_relative 'sequent/core/core'
3
+ require_relative 'sequent/util/util'
4
+ require_relative 'sequent/migrations/migrations'
@@ -2,9 +2,28 @@ require_relative 'core/event_store'
2
2
  require_relative 'core/command_service'
3
3
  require_relative 'core/transactions/no_transactions'
4
4
  require_relative 'core/aggregate_repository'
5
+ require_relative 'core/persistors/active_record_persistor'
6
+ require 'logger'
5
7
 
6
8
  module Sequent
7
9
  class Configuration
10
+
11
+ DEFAULT_VERSIONS_TABLE_NAME = 'sequent_versions'
12
+ DEFAULT_REPLAYED_IDS_TABLE_NAME = 'sequent_replayed_ids'
13
+
14
+ DEFAULT_MIGRATION_SQL_FILES_DIRECTORY = 'db/tables'
15
+ DEFAULT_DATABASE_CONFIG_DIRECTORY = 'db'
16
+
17
+ DEFAULT_VIEW_SCHEMA_NAME = 'view_schema'
18
+ DEFAULT_EVENT_STORE_SCHEMA_NAME= 'sequent_schema'
19
+
20
+ MIGRATIONS_CLASS_NAME = 'Sequent::Migrations::Projectors'
21
+
22
+ DEFAULT_NUMBER_OF_REPLAY_PROCESSES = 4
23
+
24
+ DEFAULT_OFFLINE_REPLAY_PERSISTOR_CLASS = Sequent::Core::Persistors::ActiveRecordPersistor
25
+ DEFAULT_ONLINE_REPLAY_PERSISTOR_CLASS = Sequent::Core::Persistors::ActiveRecordPersistor
26
+
8
27
  attr_accessor :aggregate_repository
9
28
 
10
29
  attr_accessor :event_store,
@@ -24,6 +43,20 @@ module Sequent
24
43
 
25
44
  attr_accessor :disable_event_handlers
26
45
 
46
+ attr_accessor :logger
47
+
48
+ attr_accessor :migration_sql_files_directory,
49
+ :view_schema_name,
50
+ :offline_replay_persistor_class,
51
+ :online_replay_persistor_class,
52
+ :number_of_replay_processes,
53
+ :database_config_directory,
54
+ :event_store_schema_name
55
+
56
+ attr_reader :migrations_class_name,
57
+ :versions_table_name,
58
+ :replayed_ids_table_name
59
+
27
60
  def self.instance
28
61
  @instance ||= new
29
62
  end
@@ -51,6 +84,40 @@ module Sequent
51
84
  self.uuid_generator = Sequent::Core::RandomUuidGenerator
52
85
  self.event_publisher = Sequent::Core::EventPublisher.new
53
86
  self.disable_event_handlers = false
87
+ self.versions_table_name = DEFAULT_VERSIONS_TABLE_NAME
88
+ self.replayed_ids_table_name = DEFAULT_REPLAYED_IDS_TABLE_NAME
89
+ self.migration_sql_files_directory = DEFAULT_MIGRATION_SQL_FILES_DIRECTORY
90
+ self.view_schema_name = DEFAULT_VIEW_SCHEMA_NAME
91
+ self.event_store_schema_name = DEFAULT_EVENT_STORE_SCHEMA_NAME
92
+ self.migrations_class_name = MIGRATIONS_CLASS_NAME
93
+ self.number_of_replay_processes = DEFAULT_NUMBER_OF_REPLAY_PROCESSES
94
+
95
+ self.offline_replay_persistor_class = DEFAULT_OFFLINE_REPLAY_PERSISTOR_CLASS
96
+ self.online_replay_persistor_class = DEFAULT_ONLINE_REPLAY_PERSISTOR_CLASS
97
+ self.database_config_directory = DEFAULT_DATABASE_CONFIG_DIRECTORY
98
+
99
+ self.logger = Logger.new(STDOUT).tap {|l| l.level = Logger::INFO }
100
+ end
101
+
102
+ def replayed_ids_table_name=(table_name)
103
+ fail ArgumentError.new('table_name can not be nil') unless table_name
104
+
105
+ @replayed_ids_table_name = table_name
106
+ Sequent::Migrations::ViewSchema::ReplayedIds.table_name = table_name
107
+ end
108
+
109
+ def versions_table_name=(table_name)
110
+ fail ArgumentError.new('table_name can not be nil') unless table_name
111
+
112
+ @versions_table_name = table_name
113
+ Sequent::Migrations::ViewSchema::Versions.table_name = table_name
54
114
  end
115
+
116
+ def migrations_class_name=(class_name)
117
+ migration_class = Class.const_get(class_name)
118
+ fail ArgumentError.new("#{migration_class} must extend Sequent::Migrations::Projectors") unless migration_class <= Sequent::Migrations::Projectors
119
+ @migrations_class_name = class_name
120
+ end
121
+
55
122
  end
56
123
  end
@@ -10,7 +10,7 @@ module Sequent
10
10
  # queried for uncommitted events. After persisting these events
11
11
  # the uncommitted events are cleared from the aggregate.
12
12
  #
13
- # The repository is keeps track of the Unit-Of-Work per thread,
13
+ # The repository keeps track of the Unit-Of-Work per thread,
14
14
  # so can be shared between threads.
15
15
  class AggregateRepository
16
16
  # Key used in thread local
@@ -1,6 +1,6 @@
1
1
  require_relative 'sequent_oj'
2
2
  require_relative 'helpers/helpers'
3
- require_relative 'record_sessions/record_sessions'
3
+ require_relative 'persistors/persistors'
4
4
  require_relative 'transactions/transactions'
5
5
  require_relative 'event'
6
6
  require_relative 'aggregate_repository'
@@ -9,7 +9,7 @@ require_relative 'base_command_handler'
9
9
  require_relative 'command'
10
10
  require_relative 'command_service'
11
11
  require_relative 'value_object'
12
- require_relative 'base_event_handler'
12
+ require_relative 'projector'
13
13
  require_relative 'event_store'
14
14
  require_relative 'event_record'
15
15
  require_relative 'command_record'
@@ -119,9 +119,9 @@ ORDER BY sequence_number ASC, (CASE event_type WHEN #{quote Sequent.configuratio
119
119
 
120
120
  PRINT_PROGRESS = lambda do |progress, done, _|
121
121
  if done
122
- puts "Done replaying #{progress} events"
122
+ Sequent.logger.debug "Done replaying #{progress} events"
123
123
  else
124
- puts "Replayed #{progress} events"
124
+ Sequent.logger.debug "Replayed #{progress} events"
125
125
  end
126
126
  end
127
127
 
@@ -2,6 +2,9 @@ require 'active_support'
2
2
  require_relative '../ext/ext'
3
3
  require_relative 'array_with_type'
4
4
  require_relative 'default_validators'
5
+ require_relative 'type_conversion_support'
6
+ require_relative 'date_time_validator'
7
+ require_relative 'association_validator'
5
8
 
6
9
  module Sequent
7
10
  module Core
@@ -3,7 +3,7 @@ module Sequent
3
3
  module Helpers
4
4
  ##
5
5
  # Creates ability to use DSL like:
6
- # class MyEventHandler < Sequent::Core::BaseEventHandler
6
+ # class MyEventHandler < Sequent::Core::Projector
7
7
  #
8
8
  # on MyEvent do |event|
9
9
  # do_some_logic
@@ -1,15 +1,21 @@
1
1
  require 'active_record'
2
+ require_relative './persistor'
2
3
 
3
4
  module Sequent
4
5
  module Core
5
- module RecordSessions
6
+ module Persistors
6
7
 
7
8
  #
8
- # Session objects are used to update view state
9
+ # The ActiveRecordPersistor uses ActiveRecord to update the projection
9
10
  #
10
- # The ActiveRecordSession object can be used when you use ActiveRecord as view state store.
11
+ # This is the default persistor in Sequent, but when your event store
12
+ # is growing it is not the best choice as persistor while rebuilding
13
+ # a projection when migrating to a new version of that projection.
11
14
  #
12
- class ActiveRecordSession
15
+ # Please see the +ReplayOptimizedPostgresPersistor+ as alternative
16
+ # for migrating projections to a new version.
17
+ class ActiveRecordPersistor
18
+ include Persistor
13
19
 
14
20
  def update_record(record_class, event, where_clause = {aggregate_id: event.aggregate_id}, options = {}, &block)
15
21
  record = record_class.unscoped.where(where_clause).first
@@ -23,10 +29,6 @@ module Sequent
23
29
  record.save!
24
30
  end
25
31
 
26
- def execute(statement)
27
- ActiveRecord::Base.connection.execute(statement)
28
- end
29
-
30
32
  def create_record(record_class, values)
31
33
  record = new_record(record_class, values)
32
34
  yield record if block_given?
@@ -46,7 +48,7 @@ module Sequent
46
48
  insert_manager.to_sql
47
49
  end.join(";")
48
50
 
49
- execute(query)
51
+ execute_sql(query)
50
52
  end
51
53
 
52
54
  def create_or_update_record(record_class, values, created_at = Time.now)
@@ -101,6 +103,14 @@ module Sequent
101
103
  record_class.unscoped.where(where_clause).last
102
104
  end
103
105
 
106
+ def execute_sql(statement)
107
+ ActiveRecord::Base.connection.execute(statement)
108
+ end
109
+
110
+ def commit
111
+ # noop
112
+ end
113
+
104
114
  private
105
115
 
106
116
  def new_record(record_class, values)
@@ -108,19 +118,11 @@ module Sequent
108
118
  end
109
119
 
110
120
  def new_insert_manager
111
- if ActiveRecord::VERSION::MAJOR <= 4
112
- Arel::InsertManager.new(ActiveRecord::Base)
113
- else
114
- Arel::InsertManager.new
115
- end
121
+ Arel::InsertManager.new
116
122
  end
117
123
 
118
124
  def convert_to_values(key, table, value)
119
- if ActiveRecord::VERSION::MAJOR <= 4
120
- [table[key], value]
121
- else
122
- [table[key], table.type_cast_for_database(key, value)]
123
- end
125
+ [table[key], table.type_cast_for_database(key, value)]
124
126
  end
125
127
  end
126
128
  end
@@ -0,0 +1,84 @@
1
+ module Sequent
2
+ module Core
3
+ module Persistors
4
+ # Defines the methods that can be implemented by the specific +Persistors+
5
+ #
6
+ # See
7
+ # - +ActiveRecordPersistor+
8
+ # - +ReplayOptimizedPostgresPersistor+
9
+ module Persistor
10
+ # Updates the view state
11
+ def update_record
12
+ fail "Method not supported in this persistor"
13
+ end
14
+
15
+ # Create a single record in the view state
16
+ def create_record
17
+ fail "Method not supported in this persistor"
18
+ end
19
+
20
+ # Creates multiple records at once in the view state
21
+ def create_records
22
+ fail "Method not supported in this persistor"
23
+ end
24
+
25
+ # Creates or updates a record in the view state.
26
+ def create_or_update_record
27
+ fail "Method not supported in this persistor"
28
+ end
29
+ # Gets a record from the view state, fails if it not exists
30
+ def get_record!
31
+ fail "Method not supported in this persistor"
32
+ end
33
+
34
+ # Gets a record from the view state, returns +nil+ if it not exists
35
+ def get_record
36
+ fail "Method not supported in this persistor"
37
+ end
38
+
39
+ # Deletes all records given a where
40
+ def delete_all_records
41
+ fail "Method not supported in this persistor"
42
+ end
43
+
44
+ # Updates all record given a where and an update clause
45
+ def update_all_records
46
+ fail "Method not supported in this persistor"
47
+ end
48
+
49
+ # Decide for yourself what to do with the records
50
+ # @deprecated
51
+ def do_with_records
52
+ fail "Method not supported in this persistor"
53
+ end
54
+
55
+ # Decide for yourself what to do with a single record
56
+ # @deprecated
57
+ def do_with_record
58
+ fail "Method not supported in this persistor"
59
+ end
60
+
61
+ # Delete a single record
62
+ # @deprecated
63
+ def delete_record
64
+ fail "Method not supported in this persistor"
65
+ end
66
+
67
+ # Find records given a where
68
+ def find_records
69
+ fail "Method not supported in this persistor"
70
+ end
71
+
72
+ # Returns the last record given a where
73
+ def last_record
74
+ fail "Method not supported in this persistor"
75
+ end
76
+
77
+ # Hook to implement for instance the persistor batches statements
78
+ def commit
79
+ fail "Method not supported in this persistor"
80
+ end
81
+ end
82
+ end
83
+ end
84
+ end
@@ -0,0 +1,3 @@
1
+ require_relative 'persistor'
2
+ require_relative 'active_record_persistor'
3
+ require_relative 'replay_optimized_postgres_persistor'
@@ -1,14 +1,22 @@
1
1
  require 'set'
2
2
  require 'active_record'
3
3
  require 'csv'
4
+ require_relative './persistor'
4
5
 
5
6
  module Sequent
6
7
  module Core
7
- module RecordSessions
8
+ module Persistors
8
9
  #
9
- # Session objects are used to update view state
10
+ # The ReplayOptimizedPostgresPersistor is optimized for bulk loading records in a Postgres database.
10
11
  #
11
- # The ReplayEventsSession is optimized for bulk loading records in a Postgres database using CSV import.
12
+ # Depending on the amount of records it uses CSV import, otherwise statements are batched
13
+ # using normal sql.
14
+ #
15
+ # Rebuilding the view state (or projection) of an aggregate typically consists
16
+ # of an initial insert and then many updates and maybe a delete. With a normal Persistor (like ActiveRecordPersistor)
17
+ # each action is executed to the database. This persitor creates an inmemory store first and finally flushes
18
+ # the in memory store to the database. This can significantly reduces the amount of queries to the database.
19
+ # E.g. 1 insert, 6 updates is only a single insert using this Persistor.
12
20
  #
13
21
  # After lot of experimenting this turned out to be the fastest way to to bulk inserts in the database.
14
22
  # You can tweak the amount of records in the CSV via +insert_with_csv_size+ before
@@ -19,7 +27,7 @@ module Sequent
19
27
  #
20
28
  # Example:
21
29
  #
22
- # class InvoiceEventHandler < Sequent::Core::Projector
30
+ # class InvoiceProjector < Sequent::Core::Projector
23
31
  # on RecipientMovedEvent do |event|
24
32
  # update_all_records InvoiceRecord, recipient_id: event.recipient.aggregate_id do |record|
25
33
  # record.recipient_street = record.recipient.street
@@ -31,11 +39,12 @@ module Sequent
31
39
  #
32
40
  # Example:
33
41
  #
34
- # ReplayEventsSession.new(
42
+ # ReplayOptimizedPostgresPersistor.new(
35
43
  # 50,
36
44
  # {InvoiceRecord => [[:recipient_id]]}
37
45
  # )
38
- class ReplayEventsSession
46
+ class ReplayOptimizedPostgresPersistor
47
+ include Persistor
39
48
 
40
49
  attr_reader :record_store
41
50
  attr_accessor :insert_with_csv_size
@@ -186,7 +195,7 @@ module Sequent
186
195
  end
187
196
  EOD
188
197
  eval("#{class_def}")
189
- struct_class = ReplayEventsSession.const_get(struct_class_name)
198
+ struct_class = ReplayOptimizedPostgresPersistor.const_get(struct_class_name)
190
199
  self.class.struct_cache[struct_class_name] = struct_class
191
200
  end
192
201
  record = struct_class.new.set_values(values)