entity_store 0.0.7 → 0.0.8

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.
@@ -0,0 +1,18 @@
1
+ module EntityStore
2
+ module Attributes
3
+ def self.included(klass)
4
+ klass.class_eval do
5
+ extend ClassMethods
6
+ end
7
+ end
8
+
9
+ module ClassMethods
10
+ def entity_value_attribute(name, klass)
11
+ define_method(name) { instance_variable_get("@#{name}") }
12
+ define_method("#{name}=") do |value|
13
+ instance_variable_set("@#{name}", value.is_a?(Hash) ? klass.new(value) : value)
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -2,14 +2,10 @@ module EntityStore
2
2
  module Entity
3
3
  attr_accessor :id
4
4
 
5
- # Holds a reference to the store used to load this entity so the same store
6
- # can be used for related entities
7
- attr_accessor :related_entity_loader
8
-
9
- attr_writer :version
10
-
11
5
  def self.included(klass)
12
6
  klass.class_eval do
7
+ include HashSerialization
8
+ include Attributes
13
9
  extend ClassMethods
14
10
  end
15
11
  end
@@ -24,8 +20,8 @@ module EntityStore
24
20
 
25
21
  # lazy loader for related entity
26
22
  define_method(name) {
27
- if instance_variable_get("@#{name}_id") && related_entity_loader
28
- instance_variable_get("@_#{name}") || instance_variable_set("@_#{name}", related_entity_loader.get(instance_variable_get("@#{name}_id")))
23
+ if instance_variable_get("@#{name}_id") && @_related_entity_loader
24
+ instance_variable_get("@_#{name}") || instance_variable_set("@_#{name}", @_related_entity_loader.get(instance_variable_get("@#{name}_id")))
29
25
  end
30
26
  }
31
27
  end
@@ -37,22 +33,32 @@ module EntityStore
37
33
 
38
34
  end
39
35
 
40
- def initialize(attr={})
41
- attr.each_pair { |k,v| self.send("#{k}=", v) }
42
- end
43
-
44
36
  def type
45
37
  self.class.name
46
38
  end
47
39
 
48
40
  def version
49
- @version ||= 1
41
+ @_version ||= 1
50
42
  end
51
-
43
+
44
+ def version=(value)
45
+ @_version = value
46
+ end
47
+
48
+ # Holds a reference to the store used to load this entity so the same store
49
+ # can be used for related entities
50
+ def related_entity_loader=(value)
51
+ @_related_entity_loader = value
52
+ end
53
+
52
54
  def pending_events
53
55
  @pending_events ||= []
54
56
  end
55
57
 
58
+ def clear_pending_events
59
+ @pending_events = []
60
+ end
61
+
56
62
  def record_event(event)
57
63
  apply_event(event)
58
64
  pending_events<<event
@@ -61,5 +67,6 @@ module EntityStore
61
67
  def apply_event(event)
62
68
  event.apply(self)
63
69
  end
70
+
64
71
  end
65
72
  end
@@ -2,21 +2,11 @@ module EntityStore
2
2
  module EntityValue
3
3
  def self.included(klass)
4
4
  klass.class_eval do
5
- extend ClassMethods
5
+ include HashSerialization
6
+ include Attributes
6
7
  end
7
8
  end
8
9
 
9
- def initialize(attr={})
10
- attr.each_pair { |k,v| self.send("#{k}=", v) if self.respond_to? "#{k}=" }
11
- end
12
-
13
- def attributes
14
- Hash[*public_methods.select {|m| m =~ /\w\=$/}.collect do |m|
15
- attribute_name = m.to_s.chop.to_sym
16
- [attribute_name, send(attribute_name).respond_to?(:attributes) ? send(attribute_name).attributes : send(attribute_name)]
17
- end.flatten]
18
- end
19
-
20
10
  def ==(other)
21
11
  attributes.each_key do |attr|
22
12
  return false unless other.respond_to?(attr) && send(attr) == other.send(attr)
@@ -24,13 +14,5 @@ module EntityStore
24
14
  return true
25
15
  end
26
16
 
27
- module ClassMethods
28
- def entity_value_attribute(name, klass)
29
- define_method(name) { instance_variable_get("@#{name}") }
30
- define_method("#{name}=") do |value|
31
- instance_variable_set("@#{name}", value.is_a?(Hash) ? klass.new(value) : value)
32
- end
33
- end
34
- end
35
17
  end
36
18
  end
@@ -2,9 +2,11 @@ module EntityStore
2
2
  module Event
3
3
  attr_accessor :entity_id, :entity_version
4
4
 
5
- def initialize(attrs={})
6
- attrs.each_pair do |key, value|
7
- send("#{key}=", value) if respond_to?("#{key}=")
5
+ def self.included(klass)
6
+ klass.class_eval do
7
+ include Attributes
8
+ include HashSerialization
9
+ extend ClassMethods
8
10
  end
9
11
  end
10
12
 
@@ -17,19 +19,6 @@ module EntityStore
17
19
  downcase
18
20
  end
19
21
 
20
- def attributes
21
- Hash[*public_methods.select {|m| m =~ /\w\=$/}.collect do |m|
22
- attribute_name = m.to_s.chop.to_sym
23
- [attribute_name, send(attribute_name).respond_to?(:attributes) ? send(attribute_name).attributes : send(attribute_name)]
24
- end.flatten]
25
- end
26
-
27
- def self.included(klass)
28
- klass.class_eval do
29
- extend ClassMethods
30
- end
31
- end
32
-
33
22
  module ClassMethods
34
23
  def time_attribute(*names)
35
24
  class_eval do
@@ -0,0 +1,32 @@
1
+ module EntityStore
2
+ module HashSerialization
3
+
4
+ def initialize(attr={})
5
+ attr.each_pair { |k,v| send("#{k}=", v) if respond_to?("#{k}=") }
6
+ end
7
+
8
+ # Public - generate attributes hash
9
+ # did use flatten but this came a-cropper when the attribute value was an array
10
+ def attributes
11
+ attrs = {}
12
+ public_methods
13
+ .select { |m| m =~ /\w\=$/ }
14
+ .select { |m| respond_to?(m.to_s.chop) }
15
+ .collect { |m| m.to_s.chop.to_sym }
16
+ .collect { |m| [m, attribute_value(send(m))] }
17
+ .each do |item| attrs[item[0]] = item[1] end
18
+ attrs
19
+ end
20
+
21
+ def attribute_value(value)
22
+ if value.respond_to?(:attributes)
23
+ value.attributes
24
+ elsif value.respond_to?(:each)
25
+ value.collect { |v| attribute_value(v) }
26
+ else
27
+ value
28
+ end
29
+ end
30
+
31
+ end
32
+ end
@@ -28,7 +28,8 @@ module EntityStore
28
28
  end
29
29
 
30
30
  def ensure_indexes
31
- events_collection.ensure_index([['entity_id', Mongo::ASCENDING], ['_id', Mongo::ASCENDING]])
31
+ events.ensure_index([['entity_id', Mongo::ASCENDING], ['_id', Mongo::ASCENDING]])
32
+ events.ensure_index([['entity_id', Mongo::ASCENDING], ['entity_version', Mongo::ASCENDING], ['_id', Mongo::ASCENDING]])
32
33
  end
33
34
 
34
35
  def add_entity(entity)
@@ -39,6 +40,20 @@ module EntityStore
39
40
  entities.update({'_id' => BSON::ObjectId.from_string(entity.id)}, { '$set' => { 'version' => entity.version } })
40
41
  end
41
42
 
43
+ # Public - create a snapshot of the entity and store in the entities collection
44
+ #
45
+ def snapshot_entity(entity)
46
+ query = {'_id' => BSON::ObjectId.from_string(entity.id)}
47
+ updates = { '$set' => { 'snapshot' => entity.attributes } }
48
+ entities.update(query, updates, { :upsert => true} )
49
+ end
50
+
51
+ # Public - remove the snapshot for an entity
52
+ #
53
+ def remove_entity_snapshot(id)
54
+ entities.update({'_id' => BSON::ObjectId.from_string(id)}, { '$unset' => { 'snapshot' => 1}})
55
+ end
56
+
42
57
  def add_event(event)
43
58
  events.insert({'_type' => event.class.name, '_entity_id' => BSON::ObjectId.from_string(event.entity_id) }.merge(event.attributes) ).to_s
44
59
  end
@@ -47,28 +62,44 @@ module EntityStore
47
62
  get_entity(id, true)
48
63
  end
49
64
 
65
+ # Public - loads the entity from the store, including any available snapshots
66
+ # then loads the events to complete the state
67
+ #
68
+ # id - String representation of BSON::ObjectId
69
+ # raise_exception - Boolean indicating whether to raise an exception if not found (default=false)
70
+ #
71
+ # Returns an object of the entity type
50
72
  def get_entity(id, raise_exception=false)
51
- begin
52
- if attrs = entities.find('_id' => BSON::ObjectId.from_string(id)).first
53
- get_type_constant(attrs['_type']).new('id' => id, 'version' => attrs['version'])
54
- else
55
- if raise_exception
56
- raise NotFound.new(id)
57
- else
58
- return nil
59
- end
60
- end
61
- rescue BSON::InvalidObjectId
62
- if raise_exception
63
- raise NotFound.new(id)
64
- else
65
- return nil
73
+ if attrs = entities.find_one('_id' => BSON::ObjectId.from_string(id))
74
+ entity = get_type_constant(attrs['_type']).new(attrs['snapshot'] || {'id' => id, 'version' => attrs['version']})
75
+
76
+ since_version = attrs['snapshot'] ? attrs['snapshot']['version'] : nil
77
+
78
+ get_events(id, since_version).each do |e|
79
+ e.apply(entity)
80
+ entity.version = e.entity_version
66
81
  end
82
+
83
+ entity
84
+ else
85
+ raise NotFound.new(id) if raise_exception
86
+ nil
67
87
  end
88
+ rescue BSON::InvalidObjectId
89
+ raise NotFound.new(id) if raise_exception
90
+ nil
68
91
  end
69
92
 
70
- def get_events(id)
71
- events.find('_entity_id' => BSON::ObjectId.from_string(id)).collect do |attrs|
93
+ def get_events(id, since_version=nil)
94
+
95
+ query = { '_entity_id' => BSON::ObjectId.from_string(id) }
96
+ query['entity_version'] = { '$gt' => since_version } if since_version
97
+
98
+ options = {
99
+ :sort => [['entity_version', Mongo::ASCENDING], ['_id', Mongo::ASCENDING]]
100
+ }
101
+
102
+ events.find(query, options).collect do |attrs|
72
103
  begin
73
104
  get_type_constant(attrs['_type']).new(attrs)
74
105
  rescue => e
@@ -1,7 +1,7 @@
1
1
  module EntityStore
2
2
  class Store
3
3
  def storage_client
4
- @storage_client || MongoEntityStore.new
4
+ @_storage_client ||= MongoEntityStore.new
5
5
  end
6
6
 
7
7
  def add(entity)
@@ -29,6 +29,7 @@ module EntityStore
29
29
  entity.id = storage_client.add_entity(entity)
30
30
  end
31
31
  add_events(entity)
32
+ snapshot_entity(entity) if entity.version % EntityStore.snapshot_threshold == 0
32
33
  end
33
34
  entity
34
35
  rescue => e
@@ -36,6 +37,15 @@ module EntityStore
36
37
  raise e
37
38
  end
38
39
 
40
+ def snapshot_entity(entity)
41
+ EntityStore.logger.info { "Store#snapshot_entity : Snapshotting #{entity.id}"}
42
+ storage_client.snapshot_entity(entity)
43
+ end
44
+
45
+ def remove_entity_snapshot(id)
46
+ storage_client.remove_entity_snapshot(id)
47
+ end
48
+
39
49
  def add_events(entity)
40
50
  entity.pending_events.each do |e|
41
51
  e.entity_id = entity.id.to_s
@@ -43,6 +53,7 @@ module EntityStore
43
53
  storage_client.add_event(e)
44
54
  end
45
55
  entity.pending_events.each {|e| EventBus.publish(entity.type, e) }
56
+ entity.clear_pending_events
46
57
  end
47
58
 
48
59
  def get!(id)
@@ -51,7 +62,6 @@ module EntityStore
51
62
 
52
63
  def get(id, raise_exception=false)
53
64
  if entity = storage_client.get_entity(id, raise_exception)
54
- storage_client.get_events(id).each { |e| e.apply(entity) }
55
65
  # assign this entity loader to allow lazy loading of related entities
56
66
  entity.related_entity_loader = self
57
67
  end
@@ -64,7 +74,7 @@ module EntityStore
64
74
  def clear_all
65
75
  storage_client.entities.drop
66
76
  storage_client.events.drop
67
- @storage_client = nil
77
+ @_storage_client = nil
68
78
  end
69
79
 
70
80
  end
@@ -1,3 +1,3 @@
1
1
  module EntityStore
2
- VERSION = "0.0.7".freeze
2
+ VERSION = "0.0.8".freeze
3
3
  end
data/lib/entity_store.rb CHANGED
@@ -9,6 +9,8 @@ module EntityStore
9
9
  require 'entity_store/mongo_entity_store'
10
10
  require 'entity_store/event_bus'
11
11
  require 'entity_store/not_found'
12
+ require 'entity_store/hash_serialization'
13
+ require 'entity_store/attributes'
12
14
 
13
15
  class << self
14
16
  def setup
@@ -35,6 +37,16 @@ module EntityStore
35
37
  @_event_subscribers ||=[]
36
38
  end
37
39
 
40
+ # Public - indicates the version increment that is used to
41
+ # decided whether a snapshot of an entity should be created when it's saved
42
+ def snapshot_threshold
43
+ @_snapshot_threshold ||= 10
44
+ end
45
+
46
+ def snapshot_threshold=(value)
47
+ @_snapshot_threshold = value
48
+ end
49
+
38
50
  def log_level
39
51
  @_log_level ||= Logger::INFO
40
52
  end
@@ -5,6 +5,8 @@ class DummyEntity
5
5
 
6
6
  related_entities :club, :user
7
7
 
8
+ attr_accessor :name, :description, :members
9
+
8
10
  end
9
11
 
10
12
  describe Entity do
@@ -66,4 +68,18 @@ describe Entity do
66
68
  end
67
69
  end
68
70
  end
71
+
72
+ describe "#attributes" do
73
+ before(:each) do
74
+ @entity = DummyEntity.new(:id => @id = random_object_id, :club_id => @club_id = random_string,
75
+ :user_id => @user_id = random_string, :name => @name = random_string, :version => @version = random_integer,
76
+ :members => [])
77
+ end
78
+
79
+ subject { @entity.attributes }
80
+
81
+ it "returns a hash of the attributes" do
82
+ subject.should eq({:id => @id, :version => @version, :name => @name, :club_id => @club_id, :user_id => @user_id, :description => nil, :members => []})
83
+ end
84
+ end
69
85
  end
@@ -32,8 +32,11 @@ describe EntityValue do
32
32
  before(:each) do
33
33
  @value = DummyEntityValue.new(:name => @name, :home => @home)
34
34
  end
35
- it "should return hash of attributes" do
36
- @value.attributes.should eq({:name => @name, :home => @home})
35
+
36
+ subject { @value.attributes }
37
+
38
+ it "should return hash of attributes and type" do
39
+ subject.should eq({:name => @name, :home => @home})
37
40
  end
38
41
  context "nested attributes" do
39
42
  before(:each) do
@@ -42,8 +45,9 @@ describe EntityValue do
42
45
  @value.home = NestedEntityValue.new(:street => @street, :town => @town)
43
46
  end
44
47
  it "should return a hash containing the nested attribute" do
45
- @value.attributes.should eq({:name => @name, :home => {:street => @street, :town => @town}})
48
+ subject.should eq({:name => @name, :home => {:street => @street, :town => @town}})
46
49
  end
50
+
47
51
  end
48
52
 
49
53
  end
@@ -94,4 +94,5 @@ describe ExternalStore do
94
94
  end
95
95
 
96
96
  end
97
+
97
98
  end
@@ -7,12 +7,80 @@ module Level1
7
7
  end
8
8
  end
9
9
 
10
+ module MongoEntityStoreSpec
11
+ class DummyEntity
12
+ include Entity
13
+
14
+ attr_accessor :name, :description
15
+
16
+ end
17
+ end
18
+
10
19
  describe MongoEntityStore do
11
20
  before(:each) do
12
21
  EntityStore.connection_profile = "mongodb://localhost/entity_store_default"
13
22
  @store = MongoEntityStore.new
14
23
  end
24
+
25
+ describe "#get_entity" do
26
+ before(:each) do
27
+ @id = random_object_id
28
+ @attrs = {
29
+ '_type' => "MongoEntityStoreSpec::DummyEntity",
30
+ 'version' => @version = random_integer
31
+ }
32
+ @entity = MongoEntityStoreSpec::DummyEntity.new
33
+ MongoEntityStoreSpec::DummyEntity.stub(:new) { @entity }
34
+ @entities_collection = mock('MongoCollection', :find_one => @attrs)
35
+ @store.stub(:entities) { @entities_collection }
36
+ @events = [
37
+ mock('Event', :apply => true, :entity_version => random_integer), mock('Event', :apply => true, :entity_version => random_integer)
38
+ ]
39
+ @store.stub(:get_events) { @events }
40
+ end
41
+
42
+ subject { @store.get_entity(@id) }
43
+
44
+ it "should attempt to retrieve the entity record from the store" do
45
+ @entities_collection.should_receive(:find_one).with({'_id' => BSON::ObjectId.from_string(@id)})
46
+ subject
47
+ end
48
+ it "should construct a new entity" do
49
+ MongoEntityStoreSpec::DummyEntity.should_receive(:new).with({'id' => @id, 'version' => @version})
50
+ subject
51
+ end
52
+ it "should retrieve it's events" do
53
+ @store.should_receive(:get_events).with(@id, nil)
54
+ subject
55
+ end
56
+ it "should apply each event to the entity" do
57
+ @events.each do |event| event.should_receive(:apply).with(@entity) end
58
+ subject
59
+ end
60
+ it "should set the entity version to that of the last event" do
61
+ subject
62
+ @entity.version.should eq(@events.last.entity_version)
63
+ end
64
+ context "when a snapshot exists" do
65
+ before(:each) do
66
+ @attrs['snapshot'] = {
67
+ 'version' => @snapshot_version = random_integer,
68
+ 'name' => @name = random_string
69
+ }
70
+ end
71
+ it "should construct a new entity with from the snapshot" do
72
+ MongoEntityStoreSpec::DummyEntity.should_receive(:new).with(@attrs['snapshot'])
73
+ subject
74
+ end
75
+ it "should load the events since the snapshot version" do
76
+ @store.should_receive(:get_events).with(@id, @snapshot_version)
77
+ subject
78
+ end
79
+ end
80
+ end
81
+
15
82
  describe "#get_entity!" do
83
+
16
84
  context "when invalid id format passed" do
17
85
 
18
86
  subject { @store.get_entity!(random_string) }
@@ -22,9 +90,6 @@ describe MongoEntityStore do
22
90
  end
23
91
  end
24
92
  context "when valid id format passed but no object exists" do
25
- before(:each) do
26
- @store = MongoEntityStore.new
27
- end
28
93
 
29
94
  subject { @store.get_entity!(random_object_id) }
30
95
 
@@ -43,4 +108,21 @@ describe MongoEntityStore do
43
108
  subject.should eq(Level1::Level2::MyClass)
44
109
  end
45
110
  end
111
+
112
+ describe "#snapshot_entity" do
113
+ before(:each) do
114
+ @entity = MongoEntityStoreSpec::DummyEntity.new(:id => random_object_id, :version => random_integer, :name => random_string)
115
+ end
116
+
117
+ subject { @store.snapshot_entity(@entity) }
118
+
119
+ it "should add a snaphot to the entity record" do
120
+ subject
121
+ saved_entity = @store.entities.find_one({'_id' => BSON::ObjectId.from_string(@entity.id)})['snapshot']
122
+ saved_entity['id'].should eq(@entity.id)
123
+ saved_entity['version'].should eq(@entity.version)
124
+ saved_entity['name'].should eq(@entity.name)
125
+ saved_entity['description'].should eq(@entity.description)
126
+ end
127
+ end
46
128
  end
@@ -79,6 +79,7 @@ describe Store do
79
79
  context "when entity has related entities loaded" do
80
80
  before(:each) do
81
81
  @entity = DummyEntityForStore.new(:id => random_string)
82
+ @entity.version = random_integer * EntityStore.snapshot_threshold + 1
82
83
  @store = Store.new
83
84
  @related_entity = mock('Entity')
84
85
  @entity.stub(:loaded_related_entities) { [ @related_entity ] }
@@ -96,13 +97,13 @@ describe Store do
96
97
  subject
97
98
  end
98
99
  end
99
-
100
100
  end
101
101
 
102
102
  describe "#do_save" do
103
103
  before(:each) do
104
104
  @new_id = random_string
105
105
  @entity = DummyEntityForStore.new(:id => random_string)
106
+ @entity.version = random_integer * EntityStore.snapshot_threshold
106
107
  @storage_client = mock("StorageClient", :save_entity => true)
107
108
  @store = Store.new
108
109
  @store.stub(:add_events)
@@ -113,8 +114,7 @@ describe Store do
113
114
  subject { @store.do_save(@entity) }
114
115
 
115
116
  it "increments the entity version number" do
116
- @entity.should_receive(:version=).with(@entity.version + 1)
117
- subject
117
+ expect { subject }.to change { @entity.version }.by 1
118
118
  end
119
119
  it "save the new entity to the store" do
120
120
  @storage_client.should_receive(:save_entity).with(@entity)
@@ -127,6 +127,11 @@ describe Store do
127
127
  it "returns a reference to the entity" do
128
128
  subject.should eq(@entity)
129
129
  end
130
+ it "should not snapshot the entity" do
131
+ @store.should_not_receive(:snapshot_entity)
132
+ subject
133
+ end
134
+
130
135
  context "when no pending events" do
131
136
  before(:each) do
132
137
  @entity.stub(:pending_events) { [] }
@@ -140,6 +145,7 @@ describe Store do
140
145
  subject
141
146
  end
142
147
  end
148
+
143
149
  context "when entity doesn't have an id" do
144
150
  before(:each) do
145
151
  @entity.id = nil
@@ -151,13 +157,25 @@ describe Store do
151
157
  subject
152
158
  end
153
159
  end
160
+
161
+ context "when entity version is commensurate with snapshotting" do
162
+ before(:each) do
163
+ @entity.version = random_integer * EntityStore.snapshot_threshold - 1
164
+ end
165
+
166
+ it "should snapshot the entity" do
167
+ @storage_client.should_receive(:snapshot_entity).with(@entity)
168
+ subject
169
+ end
170
+ end
171
+
154
172
  end
155
173
 
156
174
  describe "#get" do
157
175
  before(:each) do
158
176
  @id = random_integer
159
177
  @entity = DummyEntityForStore.new
160
- DummyEntityForStore.stub(:new).and_return(@ride)
178
+ DummyEntityForStore.stub(:new).and_return(@entity)
161
179
  @events = [mock("Event", :apply => true), mock("Event", :apply => true)]
162
180
 
163
181
  @storage_client = mock("StorageClient", :get_entity => @entity, :get_events => @events)
@@ -171,18 +189,9 @@ describe Store do
171
189
  @storage_client.should_receive(:get_entity).with(@id, false)
172
190
  subject
173
191
  end
174
- it "should retrieve the events for the entity" do
175
- @storage_client.should_receive(:get_events).with(@id)
176
- subject
177
- end
178
- it "should apply each event" do
179
- @events.each do |e|
180
- e.should_receive(:apply).with(@entity)
181
- end
182
- subject
183
- end
184
192
  it "should assign itself as the related_entity_loader" do
185
- subject.related_entity_loader.should eq(@store)
193
+ @entity.should_receive(:related_entity_loader=).with(@store)
194
+ subject
186
195
  end
187
196
  it "should return a ride" do
188
197
  subject.should eq(@entity)
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: entity_store
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.7
4
+ version: 0.0.8
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-10-13 00:00:00.000000000 Z
12
+ date: 2012-10-17 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: mongo
@@ -49,6 +49,7 @@ executables: []
49
49
  extensions: []
50
50
  extra_rdoc_files: []
51
51
  files:
52
+ - lib/entity_store/attributes.rb
52
53
  - lib/entity_store/config.rb
53
54
  - lib/entity_store/entity.rb
54
55
  - lib/entity_store/entity_value.rb
@@ -56,6 +57,7 @@ files:
56
57
  - lib/entity_store/event_bus.rb
57
58
  - lib/entity_store/event_data_object.rb
58
59
  - lib/entity_store/external_store.rb
60
+ - lib/entity_store/hash_serialization.rb
59
61
  - lib/entity_store/mongo_entity_store.rb
60
62
  - lib/entity_store/not_found.rb
61
63
  - lib/entity_store/store.rb