sequent 7.1.1 → 8.0.0

Sign up to get free protection for your applications and to get access to all the features.
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