read_model-projection 0.3.0.0.pre1
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/read_model/projection.rb +14 -0
- data/lib/read_model/projection/connection.rb +5 -0
- data/lib/read_model/projection/consumer/event_store.rb +64 -0
- data/lib/read_model/projection/controls.rb +14 -0
- data/lib/read_model/projection/controls/category.rb +7 -0
- data/lib/read_model/projection/controls/entity.rb +20 -0
- data/lib/read_model/projection/controls/entity/projection.rb +21 -0
- data/lib/read_model/projection/controls/event_data.rb +37 -0
- data/lib/read_model/projection/controls/message.rb +25 -0
- data/lib/read_model/projection/controls/name.rb +13 -0
- data/lib/read_model/projection/controls/position_store/fails.rb +26 -0
- data/lib/read_model/projection/controls/project.rb +14 -0
- data/lib/read_model/projection/controls/setup_schema.rb +7 -0
- data/lib/read_model/projection/controls/stream_name.rb +7 -0
- data/lib/read_model/projection/log.rb +10 -0
- data/lib/read_model/projection/position/setup_schema.rb +21 -0
- data/lib/read_model/projection/position/store.rb +64 -0
- data/lib/read_model/projection/project.rb +93 -0
- metadata +173 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: d5346a6345c8ec9a3961a493d07898cf206308d3
|
4
|
+
data.tar.gz: 0d61e85492220e49111c1f407d6c30ab0e40d036
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 665bea13fd5cf79dc05edaac91c1276db854297942e9f5b432d2d3adbbef37679e54627c8c7b255547769b518310b583f736c8034f27acad4375dccda28eb53b
|
7
|
+
data.tar.gz: 26424909dd9aaf252bd590ab743232966013620c6708cc9d59626a021a575d2b0f5dc5ff77981a0f4537d368a9cb3adfcbc263076148a8d014d192a7d4139c44
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'consumer'
|
2
|
+
require 'entity_cache'
|
3
|
+
require 'entity_projection'
|
4
|
+
require 'messaging'
|
5
|
+
|
6
|
+
require 'postgresql/connector'
|
7
|
+
require 'read_model/entity/sequel'
|
8
|
+
|
9
|
+
require 'read_model/projection/log'
|
10
|
+
|
11
|
+
require 'read_model/projection/connection'
|
12
|
+
require 'read_model/projection/position/setup_schema'
|
13
|
+
require 'read_model/projection/position/store'
|
14
|
+
require 'read_model/projection/project'
|
@@ -0,0 +1,64 @@
|
|
1
|
+
require 'event_source/event_store/http'
|
2
|
+
|
3
|
+
module ReadModel
|
4
|
+
module Projection
|
5
|
+
module Consumer
|
6
|
+
class EventStore
|
7
|
+
include ::Consumer
|
8
|
+
|
9
|
+
attr_accessor :entity_class
|
10
|
+
attr_accessor :projection_class
|
11
|
+
attr_accessor :projection_name
|
12
|
+
attr_accessor :stream_name
|
13
|
+
|
14
|
+
dependency :project, Project
|
15
|
+
|
16
|
+
handle do |event_data|
|
17
|
+
project.(event_data)
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.build(stream_name, entity_class:, projection_class:, projection_name:, position_store: nil, batch_size: nil, session: nil)
|
21
|
+
stream = EventSource::Stream.build stream_name
|
22
|
+
|
23
|
+
instance = new stream
|
24
|
+
|
25
|
+
instance.entity_class = entity_class
|
26
|
+
instance.position_update_interval = 1
|
27
|
+
instance.projection_class = projection_class
|
28
|
+
instance.projection_name = projection_name
|
29
|
+
|
30
|
+
instance.configure(
|
31
|
+
session: session,
|
32
|
+
batch_size: batch_size,
|
33
|
+
position_store: position_store
|
34
|
+
)
|
35
|
+
|
36
|
+
instance
|
37
|
+
end
|
38
|
+
|
39
|
+
def configure(session: nil, batch_size: nil, position_store: nil)
|
40
|
+
Position::Store.configure(
|
41
|
+
self,
|
42
|
+
projection_name,
|
43
|
+
stream.name,
|
44
|
+
position_store: position_store
|
45
|
+
)
|
46
|
+
|
47
|
+
get = EventSource::EventStore::HTTP::Get.configure(
|
48
|
+
self,
|
49
|
+
batch_size: batch_size,
|
50
|
+
session: session
|
51
|
+
)
|
52
|
+
|
53
|
+
Project.configure self, entity_class, projection_class, get: get
|
54
|
+
end
|
55
|
+
|
56
|
+
def call(*)
|
57
|
+
entity_class.db.transaction do
|
58
|
+
super
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'messaging/controls'
|
2
|
+
require 'read_model/entity/sequel/controls'
|
3
|
+
|
4
|
+
require 'read_model/projection/controls/message'
|
5
|
+
|
6
|
+
require 'read_model/projection/controls/category'
|
7
|
+
require 'read_model/projection/controls/entity'
|
8
|
+
require 'read_model/projection/controls/entity/projection'
|
9
|
+
require 'read_model/projection/controls/event_data'
|
10
|
+
require 'read_model/projection/controls/name'
|
11
|
+
require 'read_model/projection/controls/position_store/fails'
|
12
|
+
require 'read_model/projection/controls/project'
|
13
|
+
require 'read_model/projection/controls/setup_schema'
|
14
|
+
require 'read_model/projection/controls/stream_name'
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module ReadModel
|
2
|
+
module Projection
|
3
|
+
module Controls
|
4
|
+
module Entity
|
5
|
+
def self.example(entity_id: nil)
|
6
|
+
entity_id ||= Identifier::UUID::Random.get
|
7
|
+
|
8
|
+
entity = Example.new
|
9
|
+
entity.id = entity_id
|
10
|
+
entity.some_attribute = SecureRandom.hex 7
|
11
|
+
entity
|
12
|
+
end
|
13
|
+
|
14
|
+
Example = ReadModel::Entity::Sequel::Controls::Entity::Example
|
15
|
+
|
16
|
+
Association = ReadModel::Entity::Sequel::Controls::Entity::Association
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module ReadModel
|
2
|
+
module Projection
|
3
|
+
module Controls
|
4
|
+
module Entity
|
5
|
+
module Projection
|
6
|
+
class Example
|
7
|
+
include EntityProjection
|
8
|
+
|
9
|
+
apply Message::Example do |message|
|
10
|
+
entity.some_attribute = message.some_attribute
|
11
|
+
|
12
|
+
entity.example_association.find_or_new id: message.association_id do |associated_entity|
|
13
|
+
associated_entity.association_attribute = message.association_attribute
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module ReadModel
|
2
|
+
module Projection
|
3
|
+
module Controls
|
4
|
+
module EventData
|
5
|
+
def self.example(entity_id: nil, category: nil, association_id: nil, position: nil, global_position: nil)
|
6
|
+
entity_id ||= Identifier::UUID::Random.get
|
7
|
+
association_id ||= Identifier::UUID::Random.get
|
8
|
+
position ||= 0
|
9
|
+
global_position ||= position
|
10
|
+
|
11
|
+
data = {
|
12
|
+
:entity_id => entity_id,
|
13
|
+
:some_attribute => SecureRandom.hex(7),
|
14
|
+
:association_id => association_id,
|
15
|
+
:association_attribute => SecureRandom.hex(7)
|
16
|
+
}
|
17
|
+
|
18
|
+
stream_name = StreamName.example(
|
19
|
+
id: entity_id,
|
20
|
+
randomize_category: false,
|
21
|
+
category: category
|
22
|
+
)
|
23
|
+
|
24
|
+
event_data = EventSource::Controls::EventData::Read.example(
|
25
|
+
id: entity_id,
|
26
|
+
type: Message::Example.message_type,
|
27
|
+
data: data
|
28
|
+
)
|
29
|
+
event_data.stream_name = stream_name
|
30
|
+
event_data.position = position
|
31
|
+
event_data.global_position = global_position
|
32
|
+
event_data
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module ReadModel
|
2
|
+
module Projection
|
3
|
+
module Controls
|
4
|
+
module Message
|
5
|
+
def self.example(id: nil, **arguments)
|
6
|
+
event_data = EventData.example **arguments
|
7
|
+
|
8
|
+
message = Messaging::Message::Import.(event_data, Example)
|
9
|
+
message.id = id unless id.nil?
|
10
|
+
message
|
11
|
+
end
|
12
|
+
|
13
|
+
class Example
|
14
|
+
include Messaging::Message
|
15
|
+
|
16
|
+
attribute :entity_id, String
|
17
|
+
attribute :some_attribute, String
|
18
|
+
|
19
|
+
attribute :association_id, String
|
20
|
+
attribute :association_attribute, String
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module ReadModel
|
2
|
+
module Projection
|
3
|
+
module Controls
|
4
|
+
module PositionStore
|
5
|
+
module Fails
|
6
|
+
def self.example
|
7
|
+
Example.new
|
8
|
+
end
|
9
|
+
|
10
|
+
class Example
|
11
|
+
include ::Consumer::PositionStore
|
12
|
+
|
13
|
+
def get
|
14
|
+
end
|
15
|
+
|
16
|
+
def put(_)
|
17
|
+
raise Error
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
Error = Class.new StandardError
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module ReadModel
|
2
|
+
module Projection
|
3
|
+
module Controls
|
4
|
+
module Project
|
5
|
+
def self.example
|
6
|
+
entity_class = Entity::Example
|
7
|
+
projection_class = Entity::Projection::Example
|
8
|
+
|
9
|
+
ReadModel::Projection::Project.new entity_class, projection_class
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module ReadModel
|
2
|
+
module Projection
|
3
|
+
module Position
|
4
|
+
module SetupSchema
|
5
|
+
def self.call(drop_tables: nil)
|
6
|
+
drop_tables ||= false
|
7
|
+
|
8
|
+
create_table = drop_tables ? :create_table! : :create_table?
|
9
|
+
|
10
|
+
connection = Connection.get
|
11
|
+
|
12
|
+
connection.public_send create_table, :read_model_projection_positions do
|
13
|
+
String :projection, primary_key: true
|
14
|
+
String :stream_name, null: false
|
15
|
+
Integer :position, null: false
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
module ReadModel
|
2
|
+
module Projection
|
3
|
+
module Position
|
4
|
+
class Store
|
5
|
+
include Consumer::PositionStore
|
6
|
+
include Log::Dependency
|
7
|
+
|
8
|
+
configure_macro :position_store
|
9
|
+
|
10
|
+
initializer :projection_name, :stream_name
|
11
|
+
|
12
|
+
dependency :db_connection
|
13
|
+
|
14
|
+
def self.build(projection_name, stream_name, position_store: nil)
|
15
|
+
return position_store unless position_store.nil?
|
16
|
+
|
17
|
+
instance = new projection_name, stream_name
|
18
|
+
Connection.configure_connection instance
|
19
|
+
instance
|
20
|
+
end
|
21
|
+
|
22
|
+
def get
|
23
|
+
result = table.
|
24
|
+
select(:position, :stream_name).
|
25
|
+
where(:projection => projection_name).
|
26
|
+
first
|
27
|
+
|
28
|
+
unless result.nil?
|
29
|
+
unless result.fetch(:stream_name) == stream_name
|
30
|
+
error_message = "Stream name mismatch (Projection: #{projection_name}, Expected: #{stream_name}, Persisted: #{result[:stream_name]})"
|
31
|
+
logger.error { error_message }
|
32
|
+
raise StreamNameError, error_message
|
33
|
+
end
|
34
|
+
|
35
|
+
position = result.fetch :position
|
36
|
+
end
|
37
|
+
|
38
|
+
position
|
39
|
+
end
|
40
|
+
|
41
|
+
def put(position)
|
42
|
+
result = table.
|
43
|
+
insert_conflict(
|
44
|
+
:target => :projection,
|
45
|
+
:update => { :position => :excluded__position }
|
46
|
+
).
|
47
|
+
insert(
|
48
|
+
:position => position,
|
49
|
+
:projection => projection_name,
|
50
|
+
:stream_name => stream_name
|
51
|
+
)
|
52
|
+
|
53
|
+
result
|
54
|
+
end
|
55
|
+
|
56
|
+
def table
|
57
|
+
db_connection[:read_model_projection_positions]
|
58
|
+
end
|
59
|
+
|
60
|
+
StreamNameError = Class.new StandardError
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,93 @@
|
|
1
|
+
module ReadModel
|
2
|
+
module Projection
|
3
|
+
class Project
|
4
|
+
include Log::Dependency
|
5
|
+
|
6
|
+
configure :project
|
7
|
+
|
8
|
+
dependency :cache, EntityCache
|
9
|
+
dependency :get, EventSource::Get
|
10
|
+
|
11
|
+
initializer :entity_class, a(:projection)
|
12
|
+
|
13
|
+
def self.build(entity_class, projection_class, get: nil)
|
14
|
+
instance = new entity_class, projection_class
|
15
|
+
instance.configure
|
16
|
+
instance.get = get unless get.nil?
|
17
|
+
instance
|
18
|
+
end
|
19
|
+
|
20
|
+
def configure
|
21
|
+
EntityCache.configure self, self.class, attr_name: :cache
|
22
|
+
end
|
23
|
+
|
24
|
+
def call(event_data, &supplemental_action)
|
25
|
+
logger.trace { "Handling event (#{LogText.attributes self, event_data})" }
|
26
|
+
|
27
|
+
entity_id = Messaging::StreamName.get_id event_data.stream_name
|
28
|
+
|
29
|
+
entity, projected_version = get_entity entity_id
|
30
|
+
|
31
|
+
iterator = EventSource::Iterator.build get, event_data.stream_name, position: projected_version.next
|
32
|
+
|
33
|
+
(projected_version.next..event_data.position).each do |position|
|
34
|
+
if position == event_data.position
|
35
|
+
read_event_data = event_data
|
36
|
+
else
|
37
|
+
read_event_data = iterator.next
|
38
|
+
end
|
39
|
+
|
40
|
+
project entity, read_event_data, &supplemental_action
|
41
|
+
end
|
42
|
+
|
43
|
+
if projected_version < event_data.position
|
44
|
+
cache.put entity_id, entity, event_data.position
|
45
|
+
end
|
46
|
+
|
47
|
+
if event_data.position < projected_version
|
48
|
+
error_message = "Event is far ahead of entity (#{LogText.attributes self, event_data}, Projected Version: #{projected_version})"
|
49
|
+
logger.error { error_message }
|
50
|
+
raise SynchronizationError, error_message
|
51
|
+
end
|
52
|
+
|
53
|
+
entity.save
|
54
|
+
|
55
|
+
logger.info { "Projected event (#{LogText.attributes self, event_data})" }
|
56
|
+
|
57
|
+
entity
|
58
|
+
end
|
59
|
+
|
60
|
+
def get_entity(entity_id)
|
61
|
+
cache_record = cache.get entity_id
|
62
|
+
|
63
|
+
if cache_record.nil?
|
64
|
+
entity = entity_class.get entity_id
|
65
|
+
|
66
|
+
return entity, -1
|
67
|
+
else
|
68
|
+
entity = cache_record.entity
|
69
|
+
|
70
|
+
return entity, cache_record.version
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def project(entity, event_data, &supplemental_action)
|
75
|
+
projection.(entity, event_data)
|
76
|
+
|
77
|
+
supplemental_action.(event_data) if supplemental_action
|
78
|
+
end
|
79
|
+
|
80
|
+
SynchronizationError = Class.new StandardError
|
81
|
+
|
82
|
+
module LogText
|
83
|
+
def self.attributes(project, event_data)
|
84
|
+
entity_id = Messaging::StreamName.get_id event_data.stream_name
|
85
|
+
|
86
|
+
text = "Event Type: #{event_data.type}, Event Position: #{event_data.position}, Entity ID: #{entity_id}, Entity Class: #{project.entity_class}, Projection Class: #{project.projection}"
|
87
|
+
|
88
|
+
text
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
metadata
ADDED
@@ -0,0 +1,173 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: read_model-projection
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.3.0.0.pre1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Obsidian Software, Inc
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2017-01-30 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: evt-consumer
|
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: evt-entity_cache
|
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: evt-entity_projection
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: evt-messaging
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: postgresql-connector
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :runtime
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: read_model-entity-sequel
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :runtime
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: evt-messaging-event_store
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ">="
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ">="
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: test_bench
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - ">="
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - ">="
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '0'
|
125
|
+
description: " "
|
126
|
+
email: developers@obsidianexchange.com
|
127
|
+
executables: []
|
128
|
+
extensions: []
|
129
|
+
extra_rdoc_files: []
|
130
|
+
files:
|
131
|
+
- lib/read_model/projection.rb
|
132
|
+
- lib/read_model/projection/connection.rb
|
133
|
+
- lib/read_model/projection/consumer/event_store.rb
|
134
|
+
- lib/read_model/projection/controls.rb
|
135
|
+
- lib/read_model/projection/controls/category.rb
|
136
|
+
- lib/read_model/projection/controls/entity.rb
|
137
|
+
- lib/read_model/projection/controls/entity/projection.rb
|
138
|
+
- lib/read_model/projection/controls/event_data.rb
|
139
|
+
- lib/read_model/projection/controls/message.rb
|
140
|
+
- lib/read_model/projection/controls/name.rb
|
141
|
+
- lib/read_model/projection/controls/position_store/fails.rb
|
142
|
+
- lib/read_model/projection/controls/project.rb
|
143
|
+
- lib/read_model/projection/controls/setup_schema.rb
|
144
|
+
- lib/read_model/projection/controls/stream_name.rb
|
145
|
+
- lib/read_model/projection/log.rb
|
146
|
+
- lib/read_model/projection/position/setup_schema.rb
|
147
|
+
- lib/read_model/projection/position/store.rb
|
148
|
+
- lib/read_model/projection/project.rb
|
149
|
+
homepage: https://github.com/obsidian-btc/read-model-publisher
|
150
|
+
licenses:
|
151
|
+
- Not licensed for public use
|
152
|
+
metadata: {}
|
153
|
+
post_install_message:
|
154
|
+
rdoc_options: []
|
155
|
+
require_paths:
|
156
|
+
- lib
|
157
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
158
|
+
requirements:
|
159
|
+
- - ">="
|
160
|
+
- !ruby/object:Gem::Version
|
161
|
+
version: 2.2.3
|
162
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
163
|
+
requirements:
|
164
|
+
- - ">"
|
165
|
+
- !ruby/object:Gem::Version
|
166
|
+
version: 1.3.1
|
167
|
+
requirements: []
|
168
|
+
rubyforge_project:
|
169
|
+
rubygems_version: 2.6.8
|
170
|
+
signing_key:
|
171
|
+
specification_version: 4
|
172
|
+
summary: Read model projection
|
173
|
+
test_files: []
|