pg_eventstore 1.1.2 → 1.1.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +6 -0
- data/README.md +7 -29
- data/docs/admin_ui.md +35 -0
- data/lib/pg_eventstore/abstract_command.rb +2 -0
- data/lib/pg_eventstore/callbacks.rb +3 -0
- data/lib/pg_eventstore/client.rb +6 -1
- data/lib/pg_eventstore/config.rb +1 -1
- data/lib/pg_eventstore/connection.rb +9 -1
- data/lib/pg_eventstore/errors.rb +45 -26
- data/lib/pg_eventstore/event.rb +2 -1
- data/lib/pg_eventstore/event_class_resolver.rb +1 -1
- data/lib/pg_eventstore/event_deserializer.rb +8 -2
- data/lib/pg_eventstore/event_serializer.rb +2 -0
- data/lib/pg_eventstore/extensions/callbacks_extension.rb +1 -0
- data/lib/pg_eventstore/extensions/options_extension.rb +3 -1
- data/lib/pg_eventstore/queries/event_queries.rb +12 -4
- data/lib/pg_eventstore/queries/links_resolver.rb +3 -0
- data/lib/pg_eventstore/queries/partition_queries.rb +6 -0
- data/lib/pg_eventstore/queries/transaction_queries.rb +4 -0
- data/lib/pg_eventstore/queries.rb +1 -1
- data/lib/pg_eventstore/query_builders/{events_filtering_query.rb → events_filtering.rb} +3 -0
- data/lib/pg_eventstore/sql_builder.rb +18 -10
- data/lib/pg_eventstore/stream.rb +13 -2
- data/lib/pg_eventstore/subscriptions/basic_runner.rb +2 -0
- data/lib/pg_eventstore/subscriptions/commands_handler.rb +5 -3
- data/lib/pg_eventstore/subscriptions/queries/subscription_command_queries.rb +6 -4
- data/lib/pg_eventstore/subscriptions/queries/subscription_queries.rb +4 -2
- data/lib/pg_eventstore/subscriptions/queries/subscriptions_set_command_queries.rb +6 -4
- data/lib/pg_eventstore/subscriptions/queries/subscriptions_set_queries.rb +3 -0
- data/lib/pg_eventstore/subscriptions/runner_state.rb +1 -0
- data/lib/pg_eventstore/subscriptions/subscription.rb +19 -17
- data/lib/pg_eventstore/subscriptions/subscription_feeder.rb +4 -0
- data/lib/pg_eventstore/subscriptions/subscription_feeder_commands/base.rb +4 -4
- data/lib/pg_eventstore/subscriptions/subscription_handler_performance.rb +2 -1
- data/lib/pg_eventstore/subscriptions/subscription_runner.rb +5 -0
- data/lib/pg_eventstore/subscriptions/subscription_runner_commands/base.rb +4 -4
- data/lib/pg_eventstore/subscriptions/subscriptions_manager.rb +6 -4
- data/lib/pg_eventstore/subscriptions/subscriptions_set.rb +10 -10
- data/lib/pg_eventstore/version.rb +2 -1
- data/lib/pg_eventstore/web/application.rb +12 -6
- data/lib/pg_eventstore/web/paginator/base_collection.rb +15 -1
- data/lib/pg_eventstore/web/paginator/event_types_collection.rb +2 -1
- data/lib/pg_eventstore/web/paginator/events_collection.rb +7 -4
- data/lib/pg_eventstore/web/paginator/helpers.rb +3 -3
- data/lib/pg_eventstore/web/paginator/stream_contexts_collection.rb +2 -1
- data/lib/pg_eventstore/web/paginator/stream_ids_collection.rb +2 -1
- data/lib/pg_eventstore/web/paginator/stream_names_collection.rb +2 -1
- data/lib/pg_eventstore/web/subscriptions/set_collection.rb +2 -0
- data/lib/pg_eventstore/web/subscriptions/subscriptions.rb +2 -0
- data/lib/pg_eventstore/web/subscriptions/subscriptions_set.rb +2 -0
- data/lib/pg_eventstore/web/subscriptions/subscriptions_to_set_association.rb +6 -1
- data/lib/pg_eventstore/web/views/layouts/application.erb +12 -12
- data/lib/pg_eventstore.rb +6 -1
- data/pg_eventstore.gemspec +1 -1
- data/rbs_collection.lock.yaml +16 -0
- data/rbs_collection.yaml +23 -0
- data/sig/interfaces/callback.rbs +3 -0
- data/sig/interfaces/event_class_resolver.rbs +3 -0
- data/sig/interfaces/event_modifier.rbs +3 -0
- data/sig/interfaces/restart_terminator.rbs +3 -0
- data/sig/interfaces/subscription_handler.rbs +3 -0
- data/sig/pg/basic_type_registry.rbs +21 -0
- data/sig/pg/connection.rbs +407 -0
- data/sig/pg/constants.rbs +153 -0
- data/sig/pg_eventstore/abstract_command.rbs +11 -0
- data/sig/pg_eventstore/callbacks.rbs +21 -0
- data/sig/pg_eventstore/client.rbs +67 -0
- data/sig/pg_eventstore/commands/append.rbs +33 -0
- data/sig/pg_eventstore/commands/event_modifiers/prepare_link_event.rbs +24 -0
- data/sig/pg_eventstore/commands/event_modifiers/prepare_regular_event.rbs +12 -0
- data/sig/pg_eventstore/commands/link_to.rbs +17 -0
- data/sig/pg_eventstore/commands/multiple.rbs +7 -0
- data/sig/pg_eventstore/commands/read.rbs +10 -0
- data/sig/pg_eventstore/commands/regular_stream_read_paginated.rbs +32 -0
- data/sig/pg_eventstore/commands/system_stream_read_paginated.rbs +30 -0
- data/sig/pg_eventstore/config.rbs +51 -0
- data/sig/pg_eventstore/connection.rbs +30 -0
- data/sig/pg_eventstore/errors.rbs +116 -0
- data/sig/pg_eventstore/event.rbs +46 -0
- data/sig/pg_eventstore/event_class_resolver.rbs +6 -0
- data/sig/pg_eventstore/event_deserializer.rbs +20 -0
- data/sig/pg_eventstore/event_serializer.rbs +13 -0
- data/sig/pg_eventstore/extensions/callbacks_extension.rbs +23 -0
- data/sig/pg_eventstore/extensions/options_extension.rbs +37 -0
- data/sig/pg_eventstore/extensions/using_connection_extension.rbs +14 -0
- data/sig/pg_eventstore/middleware.rbs +9 -0
- data/sig/pg_eventstore/pg_connection.rbs +13 -0
- data/sig/pg_eventstore/queries/event_queries.rbs +50 -0
- data/sig/pg_eventstore/queries/links_resolver.rbs +19 -0
- data/sig/pg_eventstore/queries/partition_queries.rbs +74 -0
- data/sig/pg_eventstore/queries/transaction_queries.rbs +21 -0
- data/sig/pg_eventstore/queries.rbs +23 -0
- data/sig/pg_eventstore/query_builders/events_filtering_query.rbs +62 -0
- data/sig/pg_eventstore/sql_builder.rbs +74 -0
- data/sig/pg_eventstore/stream.rbs +40 -0
- data/sig/pg_eventstore/subscriptions/basic_runner.rbs +37 -0
- data/sig/pg_eventstore/subscriptions/command_handlers/subscription_feeder_commands.rbs +16 -0
- data/sig/pg_eventstore/subscriptions/command_handlers/subscription_runners_commands.rbs +18 -0
- data/sig/pg_eventstore/subscriptions/commands_handler.rbs +25 -0
- data/sig/pg_eventstore/subscriptions/events_processor.rbs +34 -0
- data/sig/pg_eventstore/subscriptions/extensions/base_command_extension.rbs +20 -0
- data/sig/pg_eventstore/subscriptions/extensions/command_class_lookup_extension.rbs +8 -0
- data/sig/pg_eventstore/subscriptions/queries/subscription_command_queries.rbs +56 -0
- data/sig/pg_eventstore/subscriptions/queries/subscription_queries.rbs +73 -0
- data/sig/pg_eventstore/subscriptions/queries/subscriptions_set_command_queries.rbs +39 -0
- data/sig/pg_eventstore/subscriptions/queries/subscriptions_set_queries.rbs +36 -0
- data/sig/pg_eventstore/subscriptions/runner_state.rbs +16 -0
- data/sig/pg_eventstore/subscriptions/subscription.rbs +96 -0
- data/sig/pg_eventstore/subscriptions/subscription_feeder.rbs +64 -0
- data/sig/pg_eventstore/subscriptions/subscription_feeder_commands/base.rbs +45 -0
- data/sig/pg_eventstore/subscriptions/subscription_feeder_commands/restore.rbs +8 -0
- data/sig/pg_eventstore/subscriptions/subscription_feeder_commands/start_all.rbs +8 -0
- data/sig/pg_eventstore/subscriptions/subscription_feeder_commands/stop.rbs +8 -0
- data/sig/pg_eventstore/subscriptions/subscription_feeder_commands/stop_all.rbs +8 -0
- data/sig/pg_eventstore/subscriptions/subscription_feeder_commands.rbs +8 -0
- data/sig/pg_eventstore/subscriptions/subscription_handler_performance.rbs +12 -0
- data/sig/pg_eventstore/subscriptions/subscription_runner.rbs +55 -0
- data/sig/pg_eventstore/subscriptions/subscription_runner_commands/base.rbs +47 -0
- data/sig/pg_eventstore/subscriptions/subscription_runner_commands/reset_position.rbs +11 -0
- data/sig/pg_eventstore/subscriptions/subscription_runner_commands/restore.rbs +8 -0
- data/sig/pg_eventstore/subscriptions/subscription_runner_commands/start.rbs +8 -0
- data/sig/pg_eventstore/subscriptions/subscription_runner_commands/stop.rbs +8 -0
- data/sig/pg_eventstore/subscriptions/subscription_runner_commands.rbs +8 -0
- data/sig/pg_eventstore/subscriptions/subscription_runners_feeder.rbs +13 -0
- data/sig/pg_eventstore/subscriptions/subscriptions_manager.rbs +60 -0
- data/sig/pg_eventstore/subscriptions/subscriptions_set.rbs +72 -0
- data/sig/pg_eventstore/utils.rbs +20 -0
- data/sig/pg_eventstore/version.rbs +3 -0
- data/sig/pg_eventstore/web/paginator/base_collection.rbs +51 -0
- data/sig/pg_eventstore/web/paginator/event_types_collection.rbs +15 -0
- data/sig/pg_eventstore/web/paginator/events_collection.rbs +31 -0
- data/sig/pg_eventstore/web/paginator/helpers.rbs +38 -0
- data/sig/pg_eventstore/web/paginator/stream_contexts_collection.rbs +15 -0
- data/sig/pg_eventstore/web/paginator/stream_ids_collection.rbs +15 -0
- data/sig/pg_eventstore/web/paginator/stream_names_collection.rbs +15 -0
- data/sig/pg_eventstore/web/subscriptions/helpers.rbs +48 -0
- data/sig/pg_eventstore/web/subscriptions/set_collection.rbs +18 -0
- data/sig/pg_eventstore/web/subscriptions/subscriptions.rbs +18 -0
- data/sig/pg_eventstore/web/subscriptions/subscriptions_set.rbs +18 -0
- data/sig/pg_eventstore/web/subscriptions/subscriptions_to_set_association.rbs +18 -0
- data/sig/pg_eventstore.rbs +42 -0
- metadata +91 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 12384e5023ddd60d3ff1f70006dcc8cc44d7901e4ddc7c24fcf3ab3772a00daf
|
4
|
+
data.tar.gz: d663c5aaaa96cee4f641710e7206938d9c8b06428c286b292edfaaecaaf0f4b1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e316a1a3d5a9619e4b9637aa411d9ff1cf438d4e210b02d7efd0b25e6bb1b865ff96f0cf8df2729715b5ec0b017b6254fbd51c6db9ad808b9c1a28717f7f65fc
|
7
|
+
data.tar.gz: cfecd6d0c57422130233c1fce18dd94b978c577427684ccff0610c54c8951cfbea0d91904dabfdfc73dbc6b9568fbb1d04b955344cbb53eabc08edefee0b2d16
|
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
@@ -47,44 +47,22 @@ Documentation chapters:
|
|
47
47
|
- [Subscriptions](docs/subscriptions.md)
|
48
48
|
- [Writing middlewares](docs/writing_middleware.md)
|
49
49
|
- [How to make multiple commands atomic](docs/multiple_commands.md)
|
50
|
-
|
51
|
-
## Admin web UI
|
52
|
-
|
53
|
-
`pg_eventstore` implements admin UI where you can browse various database objects. It is implemented as rack application. It doesn't have any authentication/authorization mechanism - it is your responsibility to take care of it.
|
54
|
-
|
55
|
-
### Rails integration
|
56
|
-
|
57
|
-
In your `config/routes.rb`:
|
58
|
-
|
59
|
-
```ruby
|
60
|
-
require 'pg_eventstore/web'
|
61
|
-
|
62
|
-
mount PgEventstore::Web::Application, at: '/eventstore'
|
63
|
-
```
|
64
|
-
|
65
|
-
### Standalone application
|
66
|
-
|
67
|
-
Create `config.ru` file and place next content in there:
|
68
|
-
|
69
|
-
```ruby
|
70
|
-
require 'pg_eventstore/web'
|
71
|
-
|
72
|
-
run PgEventstore::Web::Application
|
73
|
-
```
|
74
|
-
|
75
|
-
Now you can use any web server to run it.
|
50
|
+
- [Admin UI](docs/admin_ui.md)
|
76
51
|
|
77
52
|
## Development
|
78
53
|
|
79
54
|
After checking out the repo, run:
|
80
55
|
- `bundle` to install dependencies
|
81
|
-
- `docker
|
82
|
-
- `bin/setup_db` to create/re-create development and test databases, tables and related objects
|
56
|
+
- `docker compose up` to start dev/test services
|
57
|
+
- `bin/setup_db` to create/re-create development and test databases, tables and related objects
|
58
|
+
- `bundle exec rbs collection install` to install external rbs definitions
|
83
59
|
|
84
|
-
Then, run `
|
60
|
+
Then, run `bin/rspec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
85
61
|
|
86
62
|
To install this gem onto your local machine, run `bundle exec rake install`.
|
87
63
|
|
64
|
+
To run admin UI web server - run `puma` in your terminal. By default it will start web server on `http://0.0.0.0:9292`.
|
65
|
+
|
88
66
|
### Benchmarks
|
89
67
|
|
90
68
|
There is a script to help you to tests the `pg_eventstore` implementation performance. You can run it using next command:
|
data/docs/admin_ui.md
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
# Admin UI
|
2
|
+
|
3
|
+
`pg_eventstore` implements admin UI where you can browse various database objects. Key features:
|
4
|
+
|
5
|
+
- events lookup using filtering by stream context, stream name, stream id and event type
|
6
|
+
- subscriptions management and monitoring
|
7
|
+
|
8
|
+
![Events lookup](images/events_lookup.jpg)
|
9
|
+
![Subscriptions](images/subscriptions.jpg)
|
10
|
+
|
11
|
+
## Authorization
|
12
|
+
|
13
|
+
Admin UI is implemented as a rack application. It doesn't have any built-in authentication/authorization mechanism - it is your responsibility to take care of it.
|
14
|
+
|
15
|
+
### Rails integration
|
16
|
+
|
17
|
+
In your `config/routes.rb`:
|
18
|
+
|
19
|
+
```ruby
|
20
|
+
require 'pg_eventstore/web'
|
21
|
+
|
22
|
+
mount PgEventstore::Web::Application, at: '/eventstore'
|
23
|
+
```
|
24
|
+
|
25
|
+
### Standalone application
|
26
|
+
|
27
|
+
Create `config.ru` file and place next content in there:
|
28
|
+
|
29
|
+
```ruby
|
30
|
+
require 'pg_eventstore/web'
|
31
|
+
|
32
|
+
run PgEventstore::Web::Application
|
33
|
+
```
|
34
|
+
|
35
|
+
Now you can use any web server to run it.
|
@@ -97,12 +97,14 @@ module PgEventstore
|
|
97
97
|
|
98
98
|
private
|
99
99
|
|
100
|
+
# @return [void]
|
100
101
|
def run_before_callbacks(action, *args, **kwargs)
|
101
102
|
@callbacks[action][:before]&.each do |callback|
|
102
103
|
callback.call(*args, **kwargs)
|
103
104
|
end
|
104
105
|
end
|
105
106
|
|
107
|
+
# @return [Object] the result of the passed block
|
106
108
|
def run_around_callbacks(action, *args, **kwargs, &blk)
|
107
109
|
result = nil
|
108
110
|
stack = [proc { result = yield if block_given? }]
|
@@ -113,6 +115,7 @@ module PgEventstore
|
|
113
115
|
result
|
114
116
|
end
|
115
117
|
|
118
|
+
# @return [void]
|
116
119
|
def run_after_callbacks(action, *args, **kwargs)
|
117
120
|
@callbacks[action][:after]&.each do |callback|
|
118
121
|
callback.call(*args, **kwargs)
|
data/lib/pg_eventstore/client.rb
CHANGED
@@ -7,6 +7,8 @@ require_relative 'queries'
|
|
7
7
|
|
8
8
|
module PgEventstore
|
9
9
|
class Client
|
10
|
+
# @!attribute config
|
11
|
+
# @return [PgEventstore::Config]
|
10
12
|
attr_reader :config
|
11
13
|
private :config
|
12
14
|
|
@@ -111,7 +113,10 @@ module PgEventstore
|
|
111
113
|
call(stream, options: { max_count: config.max_count }.merge(options))
|
112
114
|
end
|
113
115
|
|
114
|
-
# @see {#read} for
|
116
|
+
# @see {#read} for the detailed docs
|
117
|
+
# @param stream [PgEventstore::Stream]
|
118
|
+
# @param options [Hash] request options
|
119
|
+
# @param middlewares [Array, nil]
|
115
120
|
# @return [Enumerator] enumerator will yield PgEventstore::Event
|
116
121
|
def read_paginated(stream, options: {}, middlewares: nil)
|
117
122
|
cmd_class = stream.system? ? Commands::SystemStreamReadPaginated : Commands::RegularStreamReadPaginated
|
data/lib/pg_eventstore/config.rb
CHANGED
@@ -30,7 +30,7 @@ module PgEventstore
|
|
30
30
|
# @return [Integer] Time in seconds to wait for the connection in pool to be released
|
31
31
|
option(:connection_pool_timeout) { 5 }
|
32
32
|
# @!attribute subscription_pull_interval
|
33
|
-
# @return [Float] How often Subscription should pull new events, seconds
|
33
|
+
# @return [Float, Integer] How often Subscription should pull new events, seconds
|
34
34
|
option(:subscription_pull_interval) { 1.0 }
|
35
35
|
# @!attribute subscription_max_retries
|
36
36
|
# @return [Integer] max number of retries of failed Subscription
|
@@ -38,7 +38,15 @@ module PgEventstore
|
|
38
38
|
end
|
39
39
|
end
|
40
40
|
|
41
|
-
|
41
|
+
# @!attribute uri
|
42
|
+
# @return [String]
|
43
|
+
attr_reader :uri
|
44
|
+
# @!attribute pool_size
|
45
|
+
# @return [Integer]
|
46
|
+
attr_reader :pool_size
|
47
|
+
# @!attribute pool_timeout
|
48
|
+
# @return [Integer]
|
49
|
+
attr_reader :pool_timeout
|
42
50
|
private :uri, :pool_size, :pool_timeout
|
43
51
|
|
44
52
|
# @param uri [String] PostgreSQL connection URI.
|
data/lib/pg_eventstore/errors.rb
CHANGED
@@ -22,6 +22,8 @@ module PgEventstore
|
|
22
22
|
end
|
23
23
|
|
24
24
|
class StreamNotFoundError < Error
|
25
|
+
# @!attribute stream
|
26
|
+
# @return [PgEventstore::Stream]
|
25
27
|
attr_reader :stream
|
26
28
|
|
27
29
|
# @param stream [PgEventstore::Stream]
|
@@ -32,6 +34,8 @@ module PgEventstore
|
|
32
34
|
end
|
33
35
|
|
34
36
|
class SystemStreamError < Error
|
37
|
+
# @!attribute stream
|
38
|
+
# @return [PgEventstore::Stream]
|
35
39
|
attr_reader :stream
|
36
40
|
|
37
41
|
# @param stream [PgEventstore::Stream]
|
@@ -42,7 +46,15 @@ module PgEventstore
|
|
42
46
|
end
|
43
47
|
|
44
48
|
class WrongExpectedRevisionError < Error
|
45
|
-
|
49
|
+
# @!attribute stream
|
50
|
+
# @return [PgEventstore::Stream]
|
51
|
+
attr_reader :stream
|
52
|
+
# @!attribute revision
|
53
|
+
# @return [Integer]
|
54
|
+
attr_reader :revision
|
55
|
+
# @!attribute expected_revision
|
56
|
+
# @return [Integer, Symbol]
|
57
|
+
attr_reader :expected_revision
|
46
58
|
|
47
59
|
# @param revision [Integer]
|
48
60
|
# @param expected_revision [Integer, Symbol]
|
@@ -96,29 +108,13 @@ module PgEventstore
|
|
96
108
|
end
|
97
109
|
end
|
98
110
|
|
99
|
-
class StreamDeletionError < Error
|
100
|
-
attr_reader :stream_name, :details
|
101
|
-
|
102
|
-
# @param stream_name [String]
|
103
|
-
# @param details [String]
|
104
|
-
def initialize(stream_name, details:)
|
105
|
-
@stream_name = stream_name
|
106
|
-
@details = details
|
107
|
-
super(user_friendly_message)
|
108
|
-
end
|
109
|
-
|
110
|
-
# @return [String]
|
111
|
-
def user_friendly_message
|
112
|
-
<<~TEXT.strip
|
113
|
-
Could not delete #{stream_name.inspect} stream. It seems that a stream with that \
|
114
|
-
name does not exist, has already been deleted or its state does not match the \
|
115
|
-
provided :expected_revision option. Please check #details for more info.
|
116
|
-
TEXT
|
117
|
-
end
|
118
|
-
end
|
119
|
-
|
120
111
|
class RecordNotFound < Error
|
121
|
-
|
112
|
+
# @!attribute table_name
|
113
|
+
# @return [String]
|
114
|
+
attr_reader :table_name
|
115
|
+
# @!attribute id
|
116
|
+
# @return [Integer, String]
|
117
|
+
attr_reader :id
|
122
118
|
|
123
119
|
# @param table_name [String]
|
124
120
|
# @param id [Integer, String]
|
@@ -135,7 +131,15 @@ module PgEventstore
|
|
135
131
|
end
|
136
132
|
|
137
133
|
class SubscriptionAlreadyLockedError < Error
|
138
|
-
|
134
|
+
# @!attribute set
|
135
|
+
# @return [String]
|
136
|
+
attr_reader :set
|
137
|
+
# @!attribute name
|
138
|
+
# @return [String]
|
139
|
+
attr_reader :name
|
140
|
+
# @!attribute lock_id
|
141
|
+
# @return [Integer]
|
142
|
+
attr_reader :lock_id
|
139
143
|
|
140
144
|
# @param set [String] subscriptions set name
|
141
145
|
# @param name [String] subscription's name
|
@@ -157,7 +161,15 @@ module PgEventstore
|
|
157
161
|
end
|
158
162
|
|
159
163
|
class WrongLockIdError < Error
|
160
|
-
|
164
|
+
# @!attribute set
|
165
|
+
# @return [String]
|
166
|
+
attr_reader :set
|
167
|
+
# @!attribute name
|
168
|
+
# @return [String]
|
169
|
+
attr_reader :name
|
170
|
+
# @!attribute lock_id
|
171
|
+
# @return [Integer]
|
172
|
+
attr_reader :lock_id
|
161
173
|
|
162
174
|
# @param set [String] subscriptions set name
|
163
175
|
# @param name [String] subscription's name
|
@@ -179,6 +191,8 @@ module PgEventstore
|
|
179
191
|
end
|
180
192
|
|
181
193
|
class NotPersistedEventError < Error
|
194
|
+
# @!attribute event
|
195
|
+
# @return [PgEventstore::Event]
|
182
196
|
attr_reader :event
|
183
197
|
|
184
198
|
# @param event [PgEventstore::Event]
|
@@ -194,7 +208,12 @@ module PgEventstore
|
|
194
208
|
end
|
195
209
|
|
196
210
|
class MissingPartitions < Error
|
197
|
-
|
211
|
+
# @!attribute stream
|
212
|
+
# @return [PgEventstore::Stream]
|
213
|
+
attr_reader :stream
|
214
|
+
# @!attribute event_types
|
215
|
+
# @return [Array<String>]
|
216
|
+
attr_reader :event_types
|
198
217
|
|
199
218
|
# @param stream [PgEventstore::Stream]
|
200
219
|
# @param event_types [Array<String>]
|
data/lib/pg_eventstore/event.rb
CHANGED
@@ -4,6 +4,7 @@ module PgEventstore
|
|
4
4
|
class Event
|
5
5
|
include Extensions::OptionsExtension
|
6
6
|
|
7
|
+
# @return [String] a type of link event
|
7
8
|
LINK_TYPE = '$>'
|
8
9
|
|
9
10
|
# @!attribute id
|
@@ -44,7 +45,7 @@ module PgEventstore
|
|
44
45
|
attribute(:created_at)
|
45
46
|
|
46
47
|
# Implements comparison of `PgEventstore::Event`-s. Two events matches if all of their attributes matches
|
47
|
-
# @param other [Object,
|
48
|
+
# @param other [Object, PgEventstore::Event]
|
48
49
|
# @return [Boolean]
|
49
50
|
def ==(other)
|
50
51
|
return false unless other.is_a?(PgEventstore::Event)
|
@@ -3,7 +3,12 @@
|
|
3
3
|
module PgEventstore
|
4
4
|
# @!visibility private
|
5
5
|
class EventDeserializer
|
6
|
-
|
6
|
+
# @!attribute middlewares
|
7
|
+
# @return [Array<#deserialize, #serialize>]
|
8
|
+
attr_reader :middlewares
|
9
|
+
# @!attribute event_class_resolver
|
10
|
+
# @return [#call]
|
11
|
+
attr_reader :event_class_resolver
|
7
12
|
|
8
13
|
# @param middlewares [Array<Object<#deserialize, #serialize>>]
|
9
14
|
# @param event_class_resolver [#call]
|
@@ -13,6 +18,7 @@ module PgEventstore
|
|
13
18
|
end
|
14
19
|
|
15
20
|
# @param raw_events [Array<Hash>]
|
21
|
+
# @return [Array<PgEventstore::Event>]
|
16
22
|
def deserialize_many(raw_events)
|
17
23
|
raw_events.map(&method(:deserialize))
|
18
24
|
end
|
@@ -20,7 +26,7 @@ module PgEventstore
|
|
20
26
|
# @param attrs [Hash]
|
21
27
|
# @return [PgEventstore::Event]
|
22
28
|
def deserialize(attrs)
|
23
|
-
event = event_class_resolver.call(attrs['type']).new(**attrs.transform_keys(&:to_sym))
|
29
|
+
event = event_class_resolver.call(attrs['type']).new(**attrs.except('link').transform_keys(&:to_sym))
|
24
30
|
middlewares.each do |middleware|
|
25
31
|
middleware.deserialize(event)
|
26
32
|
end
|
@@ -81,7 +81,8 @@ module PgEventstore
|
|
81
81
|
end
|
82
82
|
end
|
83
83
|
|
84
|
-
ReadonlyAttributeError
|
84
|
+
class ReadonlyAttributeError < StandardError
|
85
|
+
end
|
85
86
|
|
86
87
|
def self.included(klass)
|
87
88
|
klass.singleton_class.attr_accessor(:options)
|
@@ -122,6 +123,7 @@ module PgEventstore
|
|
122
123
|
private
|
123
124
|
|
124
125
|
# @param opt_name [Symbol]
|
126
|
+
# @return [void]
|
125
127
|
# @raise [PgEventstore::Extensions::OptionsExtension::ReadOnlyError]
|
126
128
|
def readonly_error(opt_name)
|
127
129
|
raise(
|
@@ -3,7 +3,15 @@
|
|
3
3
|
module PgEventstore
|
4
4
|
# @!visibility private
|
5
5
|
class EventQueries
|
6
|
-
|
6
|
+
# @!attribute connection
|
7
|
+
# @return [PgEventstore::Connection]
|
8
|
+
attr_reader :connection
|
9
|
+
# @!attribute serializer
|
10
|
+
# @return [PgEventstore::EventSerializer]
|
11
|
+
attr_reader :serializer
|
12
|
+
# @!attribute deserializer
|
13
|
+
# @return [PgEventstore::EventDeserializer]
|
14
|
+
attr_reader :deserializer
|
7
15
|
private :connection, :serializer, :deserializer
|
8
16
|
|
9
17
|
# @param connection [PgEventstore::Connection]
|
@@ -32,7 +40,7 @@ module PgEventstore
|
|
32
40
|
# Takes an array of potentially persisted events and loads their ids from db. Those ids can be later used to check
|
33
41
|
# whether events are actually existing events.
|
34
42
|
# @param events [Array<PgEventstore::Event>]
|
35
|
-
# @return [Array<
|
43
|
+
# @return [Array<String>]
|
36
44
|
def ids_from_db(events)
|
37
45
|
sql_builder = SQLBuilder.new.from('events').select('id')
|
38
46
|
partition_attrs = events.map { |event| [event.stream&.context, event.stream&.stream_name, event.type] }.uniq
|
@@ -72,7 +80,7 @@ module PgEventstore
|
|
72
80
|
|
73
81
|
# @param stream [PgEventstore::Stream]
|
74
82
|
# @param events [Array<PgEventstore::Event>]
|
75
|
-
# @return [PgEventstore::Event]
|
83
|
+
# @return [Array<PgEventstore::Event>]
|
76
84
|
def insert(stream, events)
|
77
85
|
sql_rows_for_insert, values = prepared_statements(stream, events)
|
78
86
|
columns = %w[id data metadata stream_revision link_id link_partition_id type context stream_name stream_id]
|
@@ -122,7 +130,7 @@ module PgEventstore
|
|
122
130
|
|
123
131
|
# @param stream [PgEventstore::Stream]
|
124
132
|
# @param options [Hash]
|
125
|
-
# @return [PgEventstore::
|
133
|
+
# @return [PgEventstore::EventsFiltering]
|
126
134
|
def events_filtering(stream, options)
|
127
135
|
return QueryBuilders::EventsFiltering.all_stream_filtering(options) if stream.all_stream?
|
128
136
|
|
@@ -3,6 +3,8 @@
|
|
3
3
|
module PgEventstore
|
4
4
|
# @!visibility private
|
5
5
|
class LinksResolver
|
6
|
+
# @!attribute connection
|
7
|
+
# @return [PgEventstore::Connection]
|
6
8
|
attr_reader :connection
|
7
9
|
private :connection
|
8
10
|
|
@@ -46,6 +48,7 @@ module PgEventstore
|
|
46
48
|
end.to_a
|
47
49
|
end
|
48
50
|
|
51
|
+
# @return [PgEventstore::PartitionQueries]
|
49
52
|
def partition_queries
|
50
53
|
PartitionQueries.new(connection)
|
51
54
|
end
|
@@ -3,6 +3,8 @@
|
|
3
3
|
module PgEventstore
|
4
4
|
# @!visibility private
|
5
5
|
class PartitionQueries
|
6
|
+
# @!attribute connection
|
7
|
+
# @return [PgEventstore::Connection]
|
6
8
|
attr_reader :connection
|
7
9
|
private :connection
|
8
10
|
|
@@ -69,6 +71,7 @@ module PgEventstore
|
|
69
71
|
end
|
70
72
|
|
71
73
|
# @param stream [PgEventstore::Stream]
|
74
|
+
# @param event_type [String]
|
72
75
|
# @param stream_name_partition_name [String]
|
73
76
|
# @return [Hash] partition attributes
|
74
77
|
def create_event_type_partition(stream, event_type, stream_name_partition_name)
|
@@ -185,6 +188,9 @@ module PgEventstore
|
|
185
188
|
"stream_names_#{Digest::MD5.hexdigest("#{stream.context}-#{stream.stream_name}")[0..5]}"
|
186
189
|
end
|
187
190
|
|
191
|
+
# @param stream [PgEventstore::Stream]
|
192
|
+
# @param event_type [String]
|
193
|
+
# @return [String]
|
188
194
|
def event_type_partition_name(stream, event_type)
|
189
195
|
"event_types_#{Digest::MD5.hexdigest("#{stream.context}-#{stream.stream_name}-#{event_type}")[0..5]}"
|
190
196
|
end
|
@@ -3,6 +3,7 @@
|
|
3
3
|
module PgEventstore
|
4
4
|
# @!visibility private
|
5
5
|
class TransactionQueries
|
6
|
+
# @return [Hash<Symbol => String>] symbol to transaction isolation level association
|
6
7
|
ISOLATION_LEVELS = {
|
7
8
|
read_committed: 'READ COMMITTED',
|
8
9
|
repeatable_read: 'REPEATABLE READ',
|
@@ -11,6 +12,8 @@ module PgEventstore
|
|
11
12
|
h.default = h[:serializable]
|
12
13
|
end.freeze
|
13
14
|
|
15
|
+
# @!attribute connection
|
16
|
+
# @return [PgEventstore::Connection]
|
14
17
|
attr_reader :connection
|
15
18
|
private :connection
|
16
19
|
|
@@ -57,6 +60,7 @@ module PgEventstore
|
|
57
60
|
retry
|
58
61
|
end
|
59
62
|
|
63
|
+
# @return [PgEventstore::PartitionQueries]
|
60
64
|
def partition_queries
|
61
65
|
PartitionQueries.new(connection)
|
62
66
|
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require_relative 'sql_builder'
|
4
|
-
require_relative 'query_builders/
|
4
|
+
require_relative 'query_builders/events_filtering'
|
5
5
|
require_relative 'queries/transaction_queries'
|
6
6
|
require_relative 'queries/event_queries'
|
7
7
|
require_relative 'queries/partition_queries'
|
@@ -4,7 +4,9 @@ module PgEventstore
|
|
4
4
|
module QueryBuilders
|
5
5
|
# @!visibility private
|
6
6
|
class EventsFiltering
|
7
|
+
# @return [Integer]
|
7
8
|
DEFAULT_LIMIT = 1_000
|
9
|
+
# @return [Hash<String => String, Symbol => String>]
|
8
10
|
SQL_DIRECTIONS = {
|
9
11
|
'asc' => 'ASC',
|
10
12
|
'desc' => 'DESC',
|
@@ -15,6 +17,7 @@ module PgEventstore
|
|
15
17
|
}.tap do |directions|
|
16
18
|
directions.default = 'ASC'
|
17
19
|
end.freeze
|
20
|
+
# @return [Array<Symbol>]
|
18
21
|
SUBSCRIPTIONS_OPTIONS = %i[from_position resolve_link_tos filter max_count].freeze
|
19
22
|
|
20
23
|
class << self
|