sequent 7.1.1 → 8.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 (78) hide show
  1. checksums.yaml +4 -4
  2. data/bin/sequent +6 -107
  3. data/db/sequent_8_migration.sql +120 -0
  4. data/db/sequent_pgsql.sql +416 -0
  5. data/db/sequent_schema.rb +11 -57
  6. data/db/sequent_schema_indexes.sql +37 -0
  7. data/db/sequent_schema_partitions.sql +34 -0
  8. data/db/sequent_schema_tables.sql +74 -0
  9. data/lib/sequent/cli/app.rb +132 -0
  10. data/lib/sequent/cli/sequent_8_migration.rb +180 -0
  11. data/lib/sequent/configuration.rb +11 -8
  12. data/lib/sequent/core/aggregate_repository.rb +2 -2
  13. data/lib/sequent/core/aggregate_root.rb +32 -9
  14. data/lib/sequent/core/aggregate_snapshotter.rb +8 -6
  15. data/lib/sequent/core/command_record.rb +27 -18
  16. data/lib/sequent/core/command_service.rb +2 -2
  17. data/lib/sequent/core/event_publisher.rb +1 -1
  18. data/lib/sequent/core/event_record.rb +37 -17
  19. data/lib/sequent/core/event_store.rb +101 -119
  20. data/lib/sequent/core/helpers/array_with_type.rb +1 -1
  21. data/lib/sequent/core/helpers/association_validator.rb +2 -2
  22. data/lib/sequent/core/helpers/attribute_support.rb +8 -8
  23. data/lib/sequent/core/helpers/equal_support.rb +3 -3
  24. data/lib/sequent/core/helpers/message_matchers/has_attrs.rb +2 -0
  25. data/lib/sequent/core/helpers/message_router.rb +2 -2
  26. data/lib/sequent/core/helpers/param_support.rb +1 -3
  27. data/lib/sequent/core/helpers/pgsql_helpers.rb +32 -0
  28. data/lib/sequent/core/helpers/string_support.rb +1 -1
  29. data/lib/sequent/core/helpers/string_to_value_parsers.rb +1 -1
  30. data/lib/sequent/core/persistors/active_record_persistor.rb +1 -1
  31. data/lib/sequent/core/persistors/replay_optimized_postgres_persistor.rb +3 -4
  32. data/lib/sequent/core/projector.rb +1 -1
  33. data/lib/sequent/core/snapshot_record.rb +44 -0
  34. data/lib/sequent/core/snapshot_store.rb +105 -0
  35. data/lib/sequent/core/stream_record.rb +10 -15
  36. data/lib/sequent/dry_run/read_only_replay_optimized_postgres_persistor.rb +1 -1
  37. data/lib/sequent/dry_run/view_schema.rb +2 -3
  38. data/lib/sequent/generator/project.rb +5 -7
  39. data/lib/sequent/generator/template_aggregate/template_aggregate/commands.rb +2 -0
  40. data/lib/sequent/generator/template_aggregate/template_aggregate/events.rb +2 -0
  41. data/lib/sequent/generator/template_aggregate/template_aggregate/template_aggregate.rb +2 -0
  42. data/lib/sequent/generator/template_aggregate/template_aggregate/template_aggregate_command_handler.rb +2 -0
  43. data/lib/sequent/generator/template_aggregate/template_aggregate.rb +2 -0
  44. data/lib/sequent/generator/template_project/Gemfile +7 -5
  45. data/lib/sequent/generator/template_project/Rakefile +4 -2
  46. data/lib/sequent/generator/template_project/app/projectors/post_projector.rb +2 -0
  47. data/lib/sequent/generator/template_project/app/records/post_record.rb +2 -0
  48. data/lib/sequent/generator/template_project/config/initializers/sequent.rb +3 -8
  49. data/lib/sequent/generator/template_project/db/migrations.rb +3 -3
  50. data/lib/sequent/generator/template_project/lib/post/commands.rb +2 -0
  51. data/lib/sequent/generator/template_project/lib/post/events.rb +2 -0
  52. data/lib/sequent/generator/template_project/lib/post/post.rb +2 -0
  53. data/lib/sequent/generator/template_project/lib/post/post_command_handler.rb +2 -0
  54. data/lib/sequent/generator/template_project/lib/post.rb +2 -0
  55. data/lib/sequent/generator/template_project/my_app.rb +2 -1
  56. data/lib/sequent/generator/template_project/spec/app/projectors/post_projector_spec.rb +2 -0
  57. data/lib/sequent/generator/template_project/spec/lib/post/post_command_handler_spec.rb +9 -2
  58. data/lib/sequent/generator/template_project/spec/spec_helper.rb +4 -7
  59. data/lib/sequent/generator.rb +1 -1
  60. data/lib/sequent/internal/aggregate_type.rb +12 -0
  61. data/lib/sequent/internal/command_type.rb +12 -0
  62. data/lib/sequent/internal/event_type.rb +12 -0
  63. data/lib/sequent/internal/internal.rb +14 -0
  64. data/lib/sequent/internal/partitioned_aggregate.rb +26 -0
  65. data/lib/sequent/internal/partitioned_command.rb +16 -0
  66. data/lib/sequent/internal/partitioned_event.rb +29 -0
  67. data/lib/sequent/migrations/grouper.rb +90 -0
  68. data/lib/sequent/migrations/sequent_schema.rb +2 -1
  69. data/lib/sequent/migrations/view_schema.rb +76 -77
  70. data/lib/sequent/rake/migration_tasks.rb +49 -24
  71. data/lib/sequent/sequent.rb +1 -0
  72. data/lib/sequent/support/database.rb +20 -16
  73. data/lib/sequent/test/time_comparison.rb +1 -1
  74. data/lib/sequent/util/timer.rb +1 -1
  75. data/lib/version.rb +1 -1
  76. metadata +102 -21
  77. data/lib/sequent/generator/template_project/db/sequent_schema.rb +0 -52
  78. data/lib/sequent/generator/template_project/ruby-version +0 -1
@@ -23,11 +23,7 @@ module Sequent
23
23
 
24
24
  database_yml = File.join(Sequent.configuration.database_config_directory, 'database.yml')
25
25
  config = YAML.safe_load(ERB.new(File.read(database_yml)).result, aliases: true)[env]
26
- if Gem.loaded_specs['activerecord'].version >= Gem::Version.create('6.1.0')
27
- ActiveRecord::Base.configurations.resolve(config).configuration_hash.with_indifferent_access
28
- else
29
- ActiveRecord::Base.resolve_config_for_connection(config)
30
- end
26
+ ActiveRecord::Base.configurations.resolve(config).configuration_hash.with_indifferent_access
31
27
  end
32
28
 
33
29
  def self.create!(db_config)
@@ -102,22 +98,31 @@ module Sequent
102
98
  establish_connection(db_config)
103
99
  end
104
100
 
105
- def self.schema_exists?(schema)
106
- ActiveRecord::Base.connection.execute(
107
- "SELECT schema_name FROM information_schema.schemata WHERE schema_name like '#{schema}'",
101
+ def self.schema_exists?(schema, event_records_table = nil)
102
+ schema_exists = ActiveRecord::Base.connection.exec_query(
103
+ 'SELECT 1 FROM information_schema.schemata WHERE schema_name LIKE $1',
104
+ 'schema_exists?',
105
+ [schema],
106
+ ).count == 1
107
+
108
+ # The ActiveRecord 7.1 schema_dumper.rb now also adds `create_schema` statements for any schema that
109
+ # is not named `public`, and in this case the schema may already be created so we check for the
110
+ # existence of the `event_records` table (or view) as well.
111
+ return schema_exists unless event_records_table
112
+
113
+ ActiveRecord::Base.connection.exec_query(
114
+ 'SELECT 1 FROM information_schema.tables WHERE table_schema LIKE $1 AND table_name LIKE $2',
115
+ 'schema_exists?',
116
+ [schema, event_records_table],
108
117
  ).count == 1
109
118
  end
110
119
 
111
120
  def self.configuration_hash
112
- if Gem.loaded_specs['activesupport'].version >= Gem::Version.create('6.1.0')
113
- ActiveRecord::Base.connection_db_config.configuration_hash
114
- else
115
- ActiveRecord::Base.connection_config
116
- end
121
+ ActiveRecord::Base.connection_db_config.configuration_hash
117
122
  end
118
123
 
119
- def schema_exists?(schema)
120
- self.class.schema_exists?(schema)
124
+ def schema_exists?(schema, event_records_table = nil)
125
+ self.class.schema_exists?(schema, event_records_table)
121
126
  end
122
127
 
123
128
  def create_schema!(schema)
@@ -131,7 +136,6 @@ module Sequent
131
136
  def execute_sql(sql)
132
137
  self.class.execute_sql(sql)
133
138
  end
134
-
135
139
  end
136
140
  end
137
141
  end
@@ -16,7 +16,7 @@ module Sequent
16
16
 
17
17
  # omit nsec in datetime comparisons
18
18
  def <=>(other)
19
- if other&.is_a?(DateTimePatches::Normalize)
19
+ if other.is_a?(DateTimePatches::Normalize)
20
20
  precision = Sequent.configuration.time_precision
21
21
  return normalize.iso8601(precision) <=> other.normalize.iso8601(precision)
22
22
  end
@@ -9,7 +9,7 @@ module Sequent
9
9
  ensure
10
10
  stop = Time.now
11
11
  seconds = stop - start
12
- Sequent.logger.debug("#{msg} in #{seconds} seconds") if seconds > 1
12
+ Sequent.logger.debug("#{msg} in #{seconds} seconds") if seconds > 1 && Sequent.logger.debug?
13
13
  end
14
14
  end
15
15
  end
data/lib/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Sequent
4
- VERSION = '7.1.1'
4
+ VERSION = '8.0.0'
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sequent
3
3
  version: !ruby/object:Gem::Version
4
- version: 7.1.1
4
+ version: 8.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Lars Vonk
@@ -12,7 +12,7 @@ authors:
12
12
  autorequire:
13
13
  bindir: bin
14
14
  cert_chain: []
15
- date: 2024-10-01 00:00:00.000000000 Z
15
+ date: 2024-12-13 00:00:00.000000000 Z
16
16
  dependencies:
17
17
  - !ruby/object:Gem::Dependency
18
18
  name: activemodel
@@ -20,28 +20,28 @@ dependencies:
20
20
  requirements:
21
21
  - - ">="
22
22
  - !ruby/object:Gem::Version
23
- version: '6.0'
23
+ version: 7.1.3
24
24
  type: :runtime
25
25
  prerelease: false
26
26
  version_requirements: !ruby/object:Gem::Requirement
27
27
  requirements:
28
28
  - - ">="
29
29
  - !ruby/object:Gem::Version
30
- version: '6.0'
30
+ version: 7.1.3
31
31
  - !ruby/object:Gem::Dependency
32
32
  name: activerecord
33
33
  requirement: !ruby/object:Gem::Requirement
34
34
  requirements:
35
35
  - - ">="
36
36
  - !ruby/object:Gem::Version
37
- version: '6.0'
37
+ version: 7.1.3
38
38
  type: :runtime
39
39
  prerelease: false
40
40
  version_requirements: !ruby/object:Gem::Requirement
41
41
  requirements:
42
42
  - - ">="
43
43
  - !ruby/object:Gem::Version
44
- version: '6.0'
44
+ version: 7.1.3
45
45
  - !ruby/object:Gem::Dependency
46
46
  name: bcrypt
47
47
  requirement: !ruby/object:Gem::Requirement
@@ -56,6 +56,34 @@ dependencies:
56
56
  - - "~>"
57
57
  - !ruby/object:Gem::Version
58
58
  version: '3.1'
59
+ - !ruby/object:Gem::Dependency
60
+ name: csv
61
+ requirement: !ruby/object:Gem::Requirement
62
+ requirements:
63
+ - - "~>"
64
+ - !ruby/object:Gem::Version
65
+ version: '3.3'
66
+ type: :runtime
67
+ prerelease: false
68
+ version_requirements: !ruby/object:Gem::Requirement
69
+ requirements:
70
+ - - "~>"
71
+ - !ruby/object:Gem::Version
72
+ version: '3.3'
73
+ - !ruby/object:Gem::Dependency
74
+ name: gli
75
+ requirement: !ruby/object:Gem::Requirement
76
+ requirements:
77
+ - - "~>"
78
+ - !ruby/object:Gem::Version
79
+ version: '2.22'
80
+ type: :runtime
81
+ prerelease: false
82
+ version_requirements: !ruby/object:Gem::Requirement
83
+ requirements:
84
+ - - "~>"
85
+ - !ruby/object:Gem::Version
86
+ version: '2.22'
59
87
  - !ruby/object:Gem::Dependency
60
88
  name: i18n
61
89
  requirement: !ruby/object:Gem::Requirement
@@ -70,20 +98,34 @@ dependencies:
70
98
  - - ">="
71
99
  - !ruby/object:Gem::Version
72
100
  version: '0'
101
+ - !ruby/object:Gem::Dependency
102
+ name: logger
103
+ requirement: !ruby/object:Gem::Requirement
104
+ requirements:
105
+ - - "~>"
106
+ - !ruby/object:Gem::Version
107
+ version: '1.6'
108
+ type: :runtime
109
+ prerelease: false
110
+ version_requirements: !ruby/object:Gem::Requirement
111
+ requirements:
112
+ - - "~>"
113
+ - !ruby/object:Gem::Version
114
+ version: '1.6'
73
115
  - !ruby/object:Gem::Dependency
74
116
  name: oj
75
117
  requirement: !ruby/object:Gem::Requirement
76
118
  requirements:
77
119
  - - "~>"
78
120
  - !ruby/object:Gem::Version
79
- version: '3'
121
+ version: '3.3'
80
122
  type: :runtime
81
123
  prerelease: false
82
124
  version_requirements: !ruby/object:Gem::Requirement
83
125
  requirements:
84
126
  - - "~>"
85
127
  - !ruby/object:Gem::Version
86
- version: '3'
128
+ version: '3.3'
87
129
  - !ruby/object:Gem::Dependency
88
130
  name: parallel
89
131
  requirement: !ruby/object:Gem::Requirement
@@ -160,6 +202,20 @@ dependencies:
160
202
  - - "~>"
161
203
  - !ruby/object:Gem::Version
162
204
  version: 0.3.6
205
+ - !ruby/object:Gem::Dependency
206
+ name: tty-prompt
207
+ requirement: !ruby/object:Gem::Requirement
208
+ requirements:
209
+ - - "~>"
210
+ - !ruby/object:Gem::Version
211
+ version: 0.23.1
212
+ type: :runtime
213
+ prerelease: false
214
+ version_requirements: !ruby/object:Gem::Requirement
215
+ requirements:
216
+ - - "~>"
217
+ - !ruby/object:Gem::Version
218
+ version: 0.23.1
163
219
  - !ruby/object:Gem::Dependency
164
220
  name: tzinfo
165
221
  requirement: !ruby/object:Gem::Requirement
@@ -174,6 +230,20 @@ dependencies:
174
230
  - - ">="
175
231
  - !ruby/object:Gem::Version
176
232
  version: '1.1'
233
+ - !ruby/object:Gem::Dependency
234
+ name: prop_check
235
+ requirement: !ruby/object:Gem::Requirement
236
+ requirements:
237
+ - - "~>"
238
+ - !ruby/object:Gem::Version
239
+ version: '1.0'
240
+ type: :development
241
+ prerelease: false
242
+ version_requirements: !ruby/object:Gem::Requirement
243
+ requirements:
244
+ - - "~>"
245
+ - !ruby/object:Gem::Version
246
+ version: '1.0'
177
247
  - !ruby/object:Gem::Dependency
178
248
  name: pry
179
249
  requirement: !ruby/object:Gem::Requirement
@@ -250,20 +320,14 @@ dependencies:
250
320
  requirements:
251
321
  - - "~>"
252
322
  - !ruby/object:Gem::Version
253
- version: '1.56'
254
- - - ">="
255
- - !ruby/object:Gem::Version
256
- version: 1.56.3
323
+ version: 1.68.0
257
324
  type: :development
258
325
  prerelease: false
259
326
  version_requirements: !ruby/object:Gem::Requirement
260
327
  requirements:
261
328
  - - "~>"
262
329
  - !ruby/object:Gem::Version
263
- version: '1.56'
264
- - - ">="
265
- - !ruby/object:Gem::Version
266
- version: 1.56.3
330
+ version: 1.68.0
267
331
  - !ruby/object:Gem::Dependency
268
332
  name: simplecov
269
333
  requirement: !ruby/object:Gem::Requirement
@@ -305,10 +369,17 @@ extensions: []
305
369
  extra_rdoc_files: []
306
370
  files:
307
371
  - bin/sequent
372
+ - db/sequent_8_migration.sql
373
+ - db/sequent_pgsql.sql
308
374
  - db/sequent_schema.rb
375
+ - db/sequent_schema_indexes.sql
376
+ - db/sequent_schema_partitions.sql
377
+ - db/sequent_schema_tables.sql
309
378
  - lib/notices.rb
310
379
  - lib/sequent.rb
311
380
  - lib/sequent/application_record.rb
381
+ - lib/sequent/cli/app.rb
382
+ - lib/sequent/cli/sequent_8_migration.rb
312
383
  - lib/sequent/configuration.rb
313
384
  - lib/sequent/core/aggregate_repository.rb
314
385
  - lib/sequent/core/aggregate_root.rb
@@ -359,6 +430,7 @@ files:
359
430
  - lib/sequent/core/helpers/message_matchers/message_matchers.rb
360
431
  - lib/sequent/core/helpers/message_router.rb
361
432
  - lib/sequent/core/helpers/param_support.rb
433
+ - lib/sequent/core/helpers/pgsql_helpers.rb
362
434
  - lib/sequent/core/helpers/secret.rb
363
435
  - lib/sequent/core/helpers/string_support.rb
364
436
  - lib/sequent/core/helpers/string_to_value_parsers.rb
@@ -376,6 +448,8 @@ files:
376
448
  - lib/sequent/core/projector.rb
377
449
  - lib/sequent/core/random_uuid_generator.rb
378
450
  - lib/sequent/core/sequent_oj.rb
451
+ - lib/sequent/core/snapshot_record.rb
452
+ - lib/sequent/core/snapshot_store.rb
379
453
  - lib/sequent/core/stream_record.rb
380
454
  - lib/sequent/core/transactions/active_record_transaction_provider.rb
381
455
  - lib/sequent/core/transactions/no_transactions.rb
@@ -406,7 +480,6 @@ files:
406
480
  - lib/sequent/generator/template_project/config/initializers/sequent.rb
407
481
  - lib/sequent/generator/template_project/db/database.yml
408
482
  - lib/sequent/generator/template_project/db/migrations.rb
409
- - lib/sequent/generator/template_project/db/sequent_schema.rb
410
483
  - lib/sequent/generator/template_project/db/tables/post_records.sql
411
484
  - lib/sequent/generator/template_project/lib/post.rb
412
485
  - lib/sequent/generator/template_project/lib/post/commands.rb
@@ -414,13 +487,20 @@ files:
414
487
  - lib/sequent/generator/template_project/lib/post/post.rb
415
488
  - lib/sequent/generator/template_project/lib/post/post_command_handler.rb
416
489
  - lib/sequent/generator/template_project/my_app.rb
417
- - lib/sequent/generator/template_project/ruby-version
418
490
  - lib/sequent/generator/template_project/spec/app/projectors/post_projector_spec.rb
419
491
  - lib/sequent/generator/template_project/spec/lib/post/post_command_handler_spec.rb
420
492
  - lib/sequent/generator/template_project/spec/spec_helper.rb
493
+ - lib/sequent/internal/aggregate_type.rb
494
+ - lib/sequent/internal/command_type.rb
495
+ - lib/sequent/internal/event_type.rb
496
+ - lib/sequent/internal/internal.rb
497
+ - lib/sequent/internal/partitioned_aggregate.rb
498
+ - lib/sequent/internal/partitioned_command.rb
499
+ - lib/sequent/internal/partitioned_event.rb
421
500
  - lib/sequent/migrations/errors.rb
422
501
  - lib/sequent/migrations/executor.rb
423
502
  - lib/sequent/migrations/functions.rb
503
+ - lib/sequent/migrations/grouper.rb
424
504
  - lib/sequent/migrations/migrations.rb
425
505
  - lib/sequent/migrations/planner.rb
426
506
  - lib/sequent/migrations/projectors.rb
@@ -448,7 +528,8 @@ files:
448
528
  homepage: https://github.com/zilverline/sequent
449
529
  licenses:
450
530
  - MIT
451
- metadata: {}
531
+ metadata:
532
+ rubygems_mfa_required: 'true'
452
533
  post_install_message:
453
534
  rdoc_options: []
454
535
  require_paths:
@@ -457,14 +538,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
457
538
  requirements:
458
539
  - - ">="
459
540
  - !ruby/object:Gem::Version
460
- version: '3.0'
541
+ version: '3.2'
461
542
  required_rubygems_version: !ruby/object:Gem::Requirement
462
543
  requirements:
463
544
  - - ">="
464
545
  - !ruby/object:Gem::Version
465
546
  version: '0'
466
547
  requirements: []
467
- rubygems_version: 3.5.16
548
+ rubygems_version: 3.4.10
468
549
  signing_key:
469
550
  specification_version: 4
470
551
  summary: Event sourcing framework for Ruby
@@ -1,52 +0,0 @@
1
- ActiveRecord::Schema.define do
2
-
3
- create_table "event_records", :force => true do |t|
4
- t.uuid "aggregate_id", :null => false
5
- t.integer "sequence_number", :null => false
6
- t.datetime "created_at", :null => false
7
- t.string "event_type", :null => false
8
- t.text "event_json", :null => false
9
- t.integer "command_record_id", :null => false
10
- t.integer "stream_record_id", :null => false
11
- t.bigint "xact_id"
12
- end
13
-
14
- execute %Q{
15
- CREATE UNIQUE INDEX unique_event_per_aggregate ON event_records (
16
- aggregate_id,
17
- sequence_number,
18
- (CASE event_type WHEN 'Sequent::Core::SnapshotEvent' THEN 0 ELSE 1 END)
19
- )
20
- }
21
- execute %Q{
22
- CREATE INDEX snapshot_events ON event_records (aggregate_id, sequence_number DESC) WHERE event_type = 'Sequent::Core::SnapshotEvent'
23
- }
24
-
25
- add_index "event_records", ["command_record_id"], :name => "index_event_records_on_command_record_id"
26
- add_index "event_records", ["event_type"], :name => "index_event_records_on_event_type"
27
- add_index "event_records", ["created_at"], :name => "index_event_records_on_created_at"
28
-
29
- create_table "command_records", :force => true do |t|
30
- t.string "user_id"
31
- t.uuid "aggregate_id"
32
- t.string "command_type", :null => false
33
- t.text "command_json", :null => false
34
- t.datetime "created_at", :null => false
35
- end
36
-
37
- create_table "stream_records", :force => true do |t|
38
- t.datetime "created_at", :null => false
39
- t.string "aggregate_type", :null => false
40
- t.uuid "aggregate_id", :null => false
41
- t.integer "snapshot_threshold"
42
- end
43
-
44
- add_index "stream_records", ["aggregate_id"], :name => "index_stream_records_on_aggregate_id", :unique => true
45
- execute %q{
46
- ALTER TABLE event_records ADD CONSTRAINT command_fkey FOREIGN KEY (command_record_id) REFERENCES command_records (id)
47
- }
48
- execute %q{
49
- ALTER TABLE event_records ADD CONSTRAINT stream_fkey FOREIGN KEY (stream_record_id) REFERENCES stream_records (id)
50
- }
51
-
52
- end