sandthorn_driver_sequel 2.1.1 → 3.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: d205c3b770d2f9e6df066e3c28bcb8cb690978e5
4
- data.tar.gz: 9fdaf52d4a30f3d1e5e40967ffdfa6554179962c
3
+ metadata.gz: bce877362844db909c0b8d1d6548ad29c41750e5
4
+ data.tar.gz: d6ad4a8929b306e4a962eb1195db49d0bbfd9de9
5
5
  SHA512:
6
- metadata.gz: 44c1d90a3247da4deaf51f811f2005b7b86ec55dd14cf1a9cd8a0124f36a8344f523dfb917a63b65a8d64b38e2afc4b99ecb3542b37cc33dc409c5f5688c60ec
7
- data.tar.gz: 0b4614730ab5f124e3f3133fefae5985d06c298312e1f4066f3af9ee78ba70709643783b97c6b4b5a4947ce7cd8b65a54d10bd854f2d92d3b56f0002dc4d7459
6
+ metadata.gz: 7b1294dc014cac377927b4e74c72270258b4b85ef4cd0a420971408d12f6536da71df03239c69328ae0c57a914556d1304c29845ca581485c8005f9f068223da
7
+ data.tar.gz: 67a03daf9055212d0d0d9610df5cc49ec6a7d51e779ce7036206861aa1e0e226b5710f0923e727e2916d50e7602b8c13e528d99343743df5ca23f1e175c31a30
data/.ruby-version CHANGED
@@ -1 +1 @@
1
- ruby-2.1
1
+ ruby-2.0
data/.travis.yml CHANGED
@@ -1,4 +1,5 @@
1
1
  language: ruby
2
2
  rvm:
3
+ - 2.2.3
3
4
  - 2.1.0
4
- - 2.0.0
5
+ - 2.0.0
data/README.md CHANGED
@@ -20,7 +20,36 @@ Or install it yourself as:
20
20
 
21
21
  ## Usage
22
22
 
23
- TODO: Write usage instructions here
23
+ ### `SandthornDriverSequel.configure`
24
+
25
+ Change the global configuration, the default data serialization for events and snapshots are YAML.
26
+
27
+ Change the serialization of events and snapshots to Oj.
28
+
29
+ ```ruby
30
+ SandthornDriverSequel.configure { |conf|
31
+ conf.event_serializer = Proc.new { |data| Oj::dump(data) }
32
+ conf.event_deserializer = Proc.new { |data| Oj::load(data) }
33
+ conf.snapshot_serializer = Proc.new { |data| Oj::dump(data) }
34
+ conf.snapshot_deserializer = Proc.new { |data| Oj::dump(data) }
35
+ }
36
+ ```
37
+
38
+ ### `SandthornDriverSequel.driver_from_connection`
39
+
40
+ Creates a driver from a Sequel connection. Its possible to send in a block like the one for `configure` to chage configuration for the driver.
41
+
42
+ ```ruby
43
+ driver = SandthornDriverSequel.driver_from_connection(connection: Sequel.sqlite)
44
+ ```
45
+
46
+ ### `SandthornDriverSequel.driver_from_url`
47
+
48
+ Creates a driver from a Sequel url. Its possible to send in a block like the one for `configure` to change configuration for the driver.
49
+
50
+ ```ruby
51
+ driver = SandthornDriverSequel.driver_from_connection(url: "<sequel url string>")
52
+ ```
24
53
 
25
54
  ## Contributing
26
55
 
@@ -1,3 +1,5 @@
1
+ require "sandthorn_driver_sequel/access"
2
+
1
3
  module SandthornDriverSequel
2
4
  class AggregateAccess < Access::Base
3
5
 
@@ -1,8 +1,16 @@
1
+ require "sandthorn_driver_sequel/access"
2
+
1
3
  module SandthornDriverSequel
2
4
  class EventAccess < Access::Base
3
5
  # = EventAccess
4
6
  # Reads and writes events.
5
7
 
8
+ def initialize storage, serializer, deserializer
9
+ @serializer = serializer
10
+ @deserializer = deserializer
11
+ super storage
12
+ end
13
+
6
14
  def store_events(aggregate, events)
7
15
  events = Utilities.array_wrap(events)
8
16
  timestamp = Time.now.utc
@@ -48,16 +56,25 @@ module SandthornDriverSequel
48
56
 
49
57
  def wrap(arg)
50
58
  events = Utilities.array_wrap(arg)
59
+ events.each { |e| e[:event_args] = deserialize(e[:event_data]) }
51
60
  events.map { |e| EventWrapper.new(e.values) }
52
61
  end
53
62
 
63
+ def deserialize event_data
64
+ @deserializer.call(event_data)
65
+ end
66
+
67
+ def serialize event_args
68
+ @serializer.call(event_args)
69
+ end
70
+
54
71
  def build_event_data(aggregate, timestamp, event)
55
72
  {
56
- aggregate_table_id: aggregate.id,
57
- aggregate_version: aggregate.aggregate_version,
58
- event_name: event.event_name,
59
- event_data: event.event_data,
60
- timestamp: timestamp
73
+ aggregate_table_id: aggregate.id,
74
+ aggregate_version: aggregate.aggregate_version,
75
+ event_name: event.event_name,
76
+ event_data: serialize(event.event_args),
77
+ timestamp: timestamp
61
78
  }
62
79
  end
63
80
 
@@ -1,21 +1,50 @@
1
+ require "sandthorn_driver_sequel/access"
2
+
1
3
  module SandthornDriverSequel
2
4
  class SnapshotAccess < Access::Base
3
5
 
6
+ def initialize storage, serializer, deserializer
7
+ @serializer = serializer
8
+ @deserializer = deserializer
9
+ super storage
10
+ end
11
+
4
12
  def find_by_aggregate_id(aggregate_id)
5
- aggregate = aggregates.find_by_aggregate_id(aggregate_id)
6
- storage.snapshots.first(aggregate_table_id: aggregate.id)
13
+
14
+ aggregate_from_table = aggregates.find_by_aggregate_id(aggregate_id)
15
+ return nil if aggregate_from_table.nil?
16
+ snapshot = storage.snapshots.first(aggregate_table_id: aggregate_from_table.id)
17
+ if snapshot
18
+ aggregate = deserialize(snapshot[:snapshot_data])
19
+
20
+ snapshot_data = {
21
+ aggregate: aggregate,
22
+ snapshot_id: snapshot.id,
23
+ aggregate_table_id: snapshot[:aggregate_table_id]
24
+ }
25
+ return SnapshotWrapper.new(snapshot_data)
26
+ end
27
+
28
+ return nil
7
29
  end
8
30
 
9
31
  def find(snapshot_id)
10
- storage.snapshots[snapshot_id]
32
+
33
+ snapshot = storage.snapshots[snapshot_id]
34
+ aggregate = deserialize(snapshot[:snapshot_data])
35
+
36
+ snapshot_data = {
37
+ aggregate: aggregate,
38
+ snapshot_id: snapshot_id,
39
+ aggregate_table_id: snapshot[:aggregate_table_id]
40
+ }
41
+
42
+ SnapshotWrapper.new(snapshot_data)
11
43
  end
12
44
 
13
- def record_snapshot(aggregate_id, snapshot_data)
14
- aggregate = aggregates.find_by_aggregate_id!(aggregate_id)
15
- previous_snapshot = find_by_aggregate_id(aggregate_id)
16
- if perform_snapshot?(aggregate, previous_snapshot)
17
- perform_snapshot(aggregate, previous_snapshot, snapshot_data)
18
- end
45
+ def record_snapshot(aggregate)
46
+ aggregate_from_table = aggregates.find_by_aggregate_id!(aggregate.aggregate_id)
47
+ perform_snapshot(aggregate, aggregate_from_table.id)
19
48
  end
20
49
 
21
50
  def obsolete(aggregate_types: [], max_event_distance: 100)
@@ -38,49 +67,38 @@ module SandthornDriverSequel
38
67
  @aggregates ||= AggregateAccess.new(storage)
39
68
  end
40
69
 
41
- def perform_snapshot?(aggregate, snapshot)
42
- return true if snapshot.nil?
43
- snapshot = SnapshotWrapper.new(snapshot)
44
- aggregate.aggregate_version > snapshot.aggregate_version
45
- end
46
-
47
- def perform_snapshot(aggregate, snapshot, snapshot_data)
48
- check_snapshot_version!(aggregate, snapshot_data)
49
- if valid_snapshot?(snapshot)
50
- update_snapshot(snapshot, snapshot_data)
70
+ def perform_snapshot(aggregate, aggregate_table_id)
71
+ current_snapshot = storage.snapshots.first(aggregate_table_id: aggregate_table_id)
72
+ snapshot = build_snapshot(aggregate)
73
+ if current_snapshot
74
+ update_snapshot(snapshot, current_snapshot.id)
51
75
  else
52
- insert_snapshot(aggregate, snapshot_data)
76
+ insert_snapshot(snapshot, aggregate_table_id)
53
77
  end
54
78
  end
55
79
 
56
- def insert_snapshot(aggregate, snapshot_data)
57
- data = build_snapshot(snapshot_data)
58
- data[:aggregate_table_id] = aggregate.id
59
- storage.snapshots.insert(data)
60
- end
61
-
62
- def build_snapshot(snapshot_data)
63
- snapshot_data = SnapshotWrapper.new(snapshot_data)
80
+ def build_snapshot(aggregate)
64
81
  {
65
- snapshot_data: snapshot_data.data,
66
- aggregate_version: snapshot_data.aggregate_version
82
+ snapshot_data: serialize(aggregate),
83
+ aggregate_version: aggregate.aggregate_version
67
84
  }
68
85
  end
69
86
 
70
- def valid_snapshot?(snapshot)
71
- snapshot && snapshot[:snapshot_data]
87
+ def insert_snapshot(snapshot, id)
88
+ snapshot[:aggregate_table_id] = id
89
+ storage.snapshots.insert(snapshot)
72
90
  end
73
91
 
74
- def update_snapshot(snapshot, snapshot_data)
75
- data = build_snapshot(snapshot_data)
76
- storage.snapshots.where(id: snapshot.id).update(data)
92
+ def update_snapshot(snapshot, id)
93
+ storage.snapshots.where(id: id).update(snapshot)
77
94
  end
78
95
 
79
- def check_snapshot_version!(aggregate, snapshot_data)
80
- snapshot = SnapshotWrapper.new(snapshot_data)
81
- if aggregate.aggregate_version < snapshot.aggregate_version
82
- raise Errors::WrongSnapshotVersionError.new(aggregate, snapshot.aggregate_version)
83
- end
96
+ def serialize aggregate
97
+ @serializer.call(aggregate)
98
+ end
99
+
100
+ def deserialize snapshot_data
101
+ @deserializer.call(snapshot_data)
84
102
  end
85
103
 
86
104
  end
@@ -14,7 +14,3 @@ module SandthornDriverSequel
14
14
  end
15
15
  end
16
16
  end
17
-
18
- require "sandthorn_driver_sequel/access/aggregate_access"
19
- require "sandthorn_driver_sequel/access/event_access"
20
- require "sandthorn_driver_sequel/access/snapshot_access"
@@ -1,13 +1,25 @@
1
+ require "sandthorn_driver_sequel/access/aggregate_access"
2
+ require "sandthorn_driver_sequel/access/event_access"
3
+ require "sandthorn_driver_sequel/access/snapshot_access"
4
+ require "sandthorn_driver_sequel/storage"
5
+
1
6
  module SandthornDriverSequel
2
7
  class EventStore
3
8
  include EventStoreContext
4
9
 
5
- attr_reader :driver, :context, :url
10
+ attr_reader :driver, :context
6
11
 
7
- def initialize url: nil, context: nil
8
- @driver = SequelDriver.new url: url
12
+ def initialize connection, configuration, context = nil
13
+ @driver = connection
9
14
  @context = context
10
- @url = url
15
+ @event_serializer = configuration.event_serializer
16
+ @event_deserializer = configuration.event_deserializer
17
+ @snapshot_serializer = configuration.snapshot_serializer
18
+ @snapshot_deserializer = configuration.snapshot_deserializer
19
+ end
20
+
21
+ def self.from_url url, configuration, context = nil
22
+ new(SequelDriver.new(url: url), configuration, context)
11
23
  end
12
24
 
13
25
  def save_events events, aggregate_id, class_name
@@ -26,10 +38,10 @@ module SandthornDriverSequel
26
38
  end
27
39
  end
28
40
 
29
- def save_snapshot aggregate_snapshot, aggregate_id
41
+ def save_snapshot aggregate
30
42
  driver.execute_in_transaction do |db|
31
43
  snapshot_access = get_snapshot_access(db)
32
- snapshot_access.record_snapshot(aggregate_id, aggregate_snapshot)
44
+ snapshot_access.record_snapshot(aggregate)
33
45
  end
34
46
  end
35
47
 
@@ -53,9 +65,7 @@ module SandthornDriverSequel
53
65
 
54
66
  def build_snapshot_event(snapshot)
55
67
  {
56
- aggregate_version: snapshot[:aggregate_version],
57
- event_data: snapshot[:snapshot_data],
58
- event_name: "aggregate_set_from_snapshot"
68
+ aggregate: snapshot.data,
59
69
  }
60
70
  end
61
71
 
@@ -87,7 +97,7 @@ module SandthornDriverSequel
87
97
  driver.execute do |db|
88
98
  snapshots = get_snapshot_access(db)
89
99
  snapshot = snapshots.find_by_aggregate_id(aggregate_id)
90
- transform_snapshot(snapshot)
100
+ snapshot.data
91
101
  end
92
102
  end
93
103
 
@@ -119,19 +129,19 @@ module SandthornDriverSequel
119
129
  end
120
130
 
121
131
  def get_aggregate_access(db)
122
- AggregateAccess.new(storage(db))
132
+ @aggregate_access ||= AggregateAccess.new(storage(db))
123
133
  end
124
134
 
125
135
  def get_event_access(db)
126
- EventAccess.new(storage(db))
136
+ @event_access ||= EventAccess.new(storage(db), @event_serializer, @event_deserializer)
127
137
  end
128
138
 
129
139
  def get_snapshot_access(db)
130
- SnapshotAccess.new(storage(db))
140
+ @snapshot_access ||= SnapshotAccess.new(storage(db), @snapshot_serializer, @snapshot_deserializer)
131
141
  end
132
142
 
133
143
  def storage(db)
134
- Storage.new(db, context)
144
+ @storage ||= Storage.new(db, @context)
135
145
  end
136
146
 
137
147
  end
@@ -3,8 +3,9 @@ module SandthornDriverSequel
3
3
  class Migration
4
4
  include EventStoreContext
5
5
  attr_reader :driver, :context
6
- def initialize url: nil, context: nil
7
- @driver = SequelDriver.new url: url
6
+ def initialize url: nil, connection: nil, context: nil
7
+ @driver = SequelDriver.new connection: connection if connection
8
+ @driver = SequelDriver.new url: url if url
8
9
  @context = context
9
10
  end
10
11
  def migrate!
@@ -3,10 +3,11 @@ require 'sequel'
3
3
  module SandthornDriverSequel
4
4
  class SequelDriver
5
5
 
6
- def initialize args = {}
7
- @url = args.fetch(:url)
6
+ def initialize(args = {})
8
7
  Sequel.default_timezone = :utc
9
- @db = Sequel.connect(@url)
8
+ @db = args.fetch(:connection) {
9
+ Sequel.connect(args.fetch(:url))
10
+ }
10
11
  end
11
12
 
12
13
  def execute
@@ -1,3 +1,3 @@
1
1
  module SandthornDriverSequel
2
- VERSION = "2.1.1"
2
+ VERSION = "3.0.0"
3
3
  end
@@ -2,7 +2,7 @@ require 'delegate'
2
2
  module SandthornDriverSequel
3
3
  class EventWrapper < SimpleDelegator
4
4
 
5
- [:aggregate_version, :event_name, :event_data, :timestamp, :aggregate_table_id].each do |attribute|
5
+ [:aggregate_version, :event_name, :event_data, :event_args, :timestamp, :aggregate_table_id].each do |attribute|
6
6
  define_method(attribute) do
7
7
  fetch(attribute)
8
8
  end
@@ -1,11 +1,19 @@
1
1
  module SandthornDriverSequel
2
2
  class SnapshotWrapper < SimpleDelegator
3
3
  def aggregate_version
4
- self[:aggregate_version]
4
+ self[:aggregate].aggregate_version
5
5
  end
6
6
 
7
7
  def data
8
- self[:event_data]
8
+ self[:aggregate]
9
+ end
10
+
11
+ def snapshot_id
12
+ self[:snapshot_id]
13
+ end
14
+
15
+ def aggregate_table_id
16
+ self[:aggregate_table_id]
9
17
  end
10
18
  end
11
19
  end
@@ -3,20 +3,104 @@ require "sandthorn_driver_sequel/utilities"
3
3
  require "sandthorn_driver_sequel/wrappers"
4
4
  require "sandthorn_driver_sequel/event_query"
5
5
  require "sandthorn_driver_sequel/event_store_context"
6
- require "sandthorn_driver_sequel/access"
7
- require "sandthorn_driver_sequel/storage"
8
6
  require 'sandthorn_driver_sequel/event_store'
9
7
  require 'sandthorn_driver_sequel/errors'
10
8
  require 'sandthorn_driver_sequel/migration'
9
+ require 'yaml'
11
10
 
12
11
  module SandthornDriverSequel
13
12
  class << self
14
- def driver_from_url url: nil, context: nil
15
- EventStore.new url: url, context: context
16
- end
13
+
17
14
  def migrate_db url: nil, context: nil
18
15
  migrator = Migration.new url: url, context: context
19
16
  migrator.migrate!
20
17
  end
18
+
19
+ def driver_from_url url: nil, context: nil
20
+
21
+ if block_given?
22
+ configuration = Configuration.new
23
+ yield(configuration)
24
+ else
25
+ configuration = self.configuration
26
+ end
27
+
28
+ EventStore.from_url(url, configuration, context)
29
+ end
30
+
31
+ def driver_from_connection connection: nil, context: nil
32
+ if block_given?
33
+ configuration = Configuration.new
34
+ yield(configuration)
35
+ else
36
+ configuration = self.configuration
37
+ end
38
+ EventStore.new(SequelDriver.new(connection: connection), configuration, context)
39
+ end
40
+
41
+ def configure
42
+ yield(configuration) if block_given?
43
+ end
44
+
45
+ def configuration
46
+ @configuration ||= Configuration.new
47
+ end
48
+
49
+ private
50
+
51
+ class Configuration
52
+
53
+ #event
54
+ def event_serializer=(block)
55
+ @event_serializer = block
56
+ end
57
+
58
+ def event_deserializer=(block)
59
+ @event_deserializer = block
60
+ end
61
+
62
+ def event_serializer
63
+ @event_serializer || default_event_serializer
64
+ end
65
+
66
+ def event_deserializer
67
+ @event_deserializer || default_event_deserializer
68
+ end
69
+
70
+ def default_event_serializer
71
+ -> (data) { YAML.dump(data) }
72
+ end
73
+
74
+ def default_event_deserializer
75
+ -> (data) { YAML.load(data) }
76
+ end
77
+
78
+ #snapshot
79
+ def snapshot_serializer=(block)
80
+ @snapshot_serializer = block
81
+ end
82
+
83
+ def snapshot_deserializer=(block)
84
+ @snapshot_deserializer = block
85
+ end
86
+
87
+ def snapshot_serializer
88
+ @snapshot_serializer || default_snapshot_serializer
89
+ end
90
+
91
+ def snapshot_deserializer
92
+ @snapshot_deserializer || default_snapshot_deserializer
93
+ end
94
+
95
+ def default_snapshot_serializer
96
+ -> (data) { YAML.dump(data) }
97
+ end
98
+
99
+ def default_snapshot_deserializer
100
+ -> (data) { YAML.load(data) }
101
+ end
102
+
103
+
104
+ end
21
105
  end
22
106
  end