midnight-mongoid 0.0.1
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.
- checksums.yaml +7 -0
- data/lib/midnight/mongoid.rb +15 -0
- data/lib/midnight/mongoid/interactor.rb +59 -0
- data/lib/midnight/mongoid/stale_object_error.rb +10 -0
- data/lib/midnight/mongoid/state.rb +63 -0
- data/lib/midnight/mongoid/version.rb +5 -0
- metadata +92 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 110a629ede9758a000259365eafad6b33f61be2d626734f2ca5a073c8960c421
|
4
|
+
data.tar.gz: 0e02ab35bb3ab00cc90f05771d73def5de9decddd59ed41f3d19bdcbc2acbdfd
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: e77c28ddceabf7e17bcdd2a40de20a7a8aa53f4a0917cf0feb7e1eb9bb9c7778f7c9d10cda1d231e968e77ff7f2857c84b8cd2d662b04c5263f009c0ab0815c4
|
7
|
+
data.tar.gz: 9180e1eda75613120e731b2621b6169799fe074163c53013b0b07603d157bc10b019a364b488dc7564ce1ef2b442ffe194692d22dff8adc4e24350838447eeb6
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'active_support/dependencies/autoload'
|
2
|
+
require_relative 'mongoid/version'
|
3
|
+
|
4
|
+
module Midnight
|
5
|
+
module Mongoid
|
6
|
+
module Error
|
7
|
+
end
|
8
|
+
|
9
|
+
extend ::ActiveSupport::Autoload
|
10
|
+
|
11
|
+
autoload :Interactor
|
12
|
+
autoload :StaleObjectError
|
13
|
+
autoload :State
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
require 'active_support/core_ext/object'
|
2
|
+
require 'midnight/business_logic'
|
3
|
+
|
4
|
+
module Midnight
|
5
|
+
module Mongoid
|
6
|
+
DEFAULT_COMMAND_VALIDATOR = lambda(&:validate!)
|
7
|
+
|
8
|
+
class Interactor
|
9
|
+
def initialize(\
|
10
|
+
aggregate_key:,
|
11
|
+
build_aggregate:,
|
12
|
+
event_handler: Commons::NULL_EVENT_HANDLER,
|
13
|
+
command_validator: DEFAULT_COMMAND_VALIDATOR,
|
14
|
+
state_persistence: State,
|
15
|
+
advance_state_metadata: lambda(&:advance_metadata),
|
16
|
+
save_state: lambda(&:save!)
|
17
|
+
)
|
18
|
+
@aggregate_key = aggregate_key
|
19
|
+
@build_aggregate = build_aggregate
|
20
|
+
@event_handler = event_handler
|
21
|
+
@command_validator = command_validator
|
22
|
+
@state_persistence = state_persistence
|
23
|
+
@advance_state_metadata = advance_state_metadata
|
24
|
+
@save_state = save_state
|
25
|
+
freeze
|
26
|
+
end
|
27
|
+
|
28
|
+
def call(*commands)
|
29
|
+
commands.each(&@command_validator)
|
30
|
+
transaction do |aggregate|
|
31
|
+
commands.each(&aggregate.method(:dispatch))
|
32
|
+
aggregate.pending_events
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
private
|
37
|
+
|
38
|
+
def transaction(&aggregate_operator)
|
39
|
+
state_record = @state_persistence.load(
|
40
|
+
key: @aggregate_key
|
41
|
+
)
|
42
|
+
aggregate = @build_aggregate.call(
|
43
|
+
state: state_record.state
|
44
|
+
)
|
45
|
+
state_metadata = state_record.metadata
|
46
|
+
pending_events = aggregate_operator.call(aggregate)
|
47
|
+
return pending_events if pending_events.blank?
|
48
|
+
state_record.state = aggregate.state
|
49
|
+
@advance_state_metadata.call(state_record, pending_events)
|
50
|
+
@save_state.call(state_record)
|
51
|
+
@event_handler.call(
|
52
|
+
pending_events,
|
53
|
+
state_metadata
|
54
|
+
)
|
55
|
+
pending_events
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
require 'active_support/core_ext/object'
|
2
|
+
require 'active_support/core_ext/hash'
|
3
|
+
require 'mongoid'
|
4
|
+
|
5
|
+
module Midnight
|
6
|
+
module Mongoid
|
7
|
+
class State
|
8
|
+
include ::Mongoid::Document
|
9
|
+
store_in collection: 'aggregate_states'
|
10
|
+
|
11
|
+
field :state, type: ::Hash
|
12
|
+
field :next_position, type: Integer, default: 1
|
13
|
+
field :lock_version, type: Integer, default: 0
|
14
|
+
|
15
|
+
def metadata
|
16
|
+
{
|
17
|
+
next_position: next_position,
|
18
|
+
state_id: _id,
|
19
|
+
aggregate_key: _id,
|
20
|
+
}
|
21
|
+
end
|
22
|
+
|
23
|
+
def advance_metadata(events)
|
24
|
+
self.next_position += events.length
|
25
|
+
end
|
26
|
+
|
27
|
+
def state=(new_state)
|
28
|
+
@state_changed = true
|
29
|
+
super(new_state)
|
30
|
+
end
|
31
|
+
|
32
|
+
def save!
|
33
|
+
return true unless @state_changed
|
34
|
+
raise StaleObjectError unless _id.present?
|
35
|
+
update_result = collection.update_one({
|
36
|
+
_id: _id,
|
37
|
+
lock_version: self.lock_version,
|
38
|
+
}.with_indifferent_access, {
|
39
|
+
'$set': {
|
40
|
+
state: self.state,
|
41
|
+
next_position: self.next_position,
|
42
|
+
}.compact,
|
43
|
+
'$inc': {
|
44
|
+
lock_version: 1
|
45
|
+
}
|
46
|
+
}.with_indifferent_access)
|
47
|
+
raise StaleObjectError if update_result.matched_count < 1
|
48
|
+
!!(self.lock_version += 1)
|
49
|
+
end
|
50
|
+
|
51
|
+
class << self
|
52
|
+
def load(key:, **_)
|
53
|
+
where(
|
54
|
+
_id: key
|
55
|
+
).first_or_create!
|
56
|
+
rescue ::Mongo::Error::OperationFailure => e
|
57
|
+
raise e unless e.code == 11000
|
58
|
+
retry
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
metadata
ADDED
@@ -0,0 +1,92 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: midnight-mongoid
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Sarun Rattanasiri
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2019-08-31 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: activesupport
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: midnight-business_logic
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: mongoid
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: 7.0.0
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 7.0.0
|
55
|
+
description: This gem provides the integration between Midnight::BusinessLogic and
|
56
|
+
the ODM officially supported by MongoDB Inc., Mongoid
|
57
|
+
email: midnight_w@gmx.tw
|
58
|
+
executables: []
|
59
|
+
extensions: []
|
60
|
+
extra_rdoc_files: []
|
61
|
+
files:
|
62
|
+
- lib/midnight/mongoid.rb
|
63
|
+
- lib/midnight/mongoid/interactor.rb
|
64
|
+
- lib/midnight/mongoid/stale_object_error.rb
|
65
|
+
- lib/midnight/mongoid/state.rb
|
66
|
+
- lib/midnight/mongoid/version.rb
|
67
|
+
homepage: https://slime.systems/
|
68
|
+
licenses:
|
69
|
+
- BSD-3-Clause
|
70
|
+
metadata:
|
71
|
+
homepage_uri: https://slime.systems/
|
72
|
+
source_code_uri: https://github.com/rails/rails/tree/v0.0.1
|
73
|
+
post_install_message:
|
74
|
+
rdoc_options: []
|
75
|
+
require_paths:
|
76
|
+
- lib
|
77
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
78
|
+
requirements:
|
79
|
+
- - ">="
|
80
|
+
- !ruby/object:Gem::Version
|
81
|
+
version: '0'
|
82
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
83
|
+
requirements:
|
84
|
+
- - ">="
|
85
|
+
- !ruby/object:Gem::Version
|
86
|
+
version: '0'
|
87
|
+
requirements: []
|
88
|
+
rubygems_version: 3.0.3
|
89
|
+
signing_key:
|
90
|
+
specification_version: 4
|
91
|
+
summary: A MongoDB integration of Midnight::BusinessLogic
|
92
|
+
test_files: []
|