toystore 0.6.6 → 0.7.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.
data/LOGGING.rdoc CHANGED
@@ -9,8 +9,4 @@ What the 3 letter codes mean when they show up in logging:
9
9
  IMS: write to identity map
10
10
  IMD: delete from identity map
11
11
 
12
- RTG: get cache read
13
- RTS: get cache set
14
- WTS: cache write set
15
-
16
12
  IEM: invalid embedded document
data/lib/toy/attribute.rb CHANGED
@@ -54,7 +54,7 @@ module Toy
54
54
  options[:abbr]
55
55
  end
56
56
 
57
- def store_key
57
+ def persisted_name
58
58
  abbr? ? abbr : name
59
59
  end
60
60
 
@@ -40,8 +40,8 @@ module Toy
40
40
  end
41
41
 
42
42
  def reload
43
- if attrs = store.read(store_key)
44
- attrs['id'] = store_key
43
+ if attrs = store.read(id)
44
+ attrs['id'] = id
45
45
  instance_variables.each { |ivar| instance_variable_set(ivar, nil) }
46
46
  initialize_attributes_with_defaults
47
47
  send(:attributes=, attrs, new_record?)
@@ -65,7 +65,7 @@ module Toy
65
65
  {}.tap do |attrs|
66
66
  self.class.attributes.each do |name, attribute|
67
67
  next if attribute.virtual?
68
- attrs[attribute.store_key] = attribute.to_store(read_attribute(attribute.name))
68
+ attrs[attribute.persisted_name] = attribute.to_store(read_attribute(attribute.name))
69
69
  end
70
70
  end.merge(embedded_attributes)
71
71
  end
@@ -47,17 +47,16 @@ module Toy
47
47
 
48
48
  def get_from_identity_map(id)
49
49
  return nil unless identity_map_on?
50
- key = store_key(id)
51
- if record = identity_map[key]
52
- logger.debug("ToyStore IMG #{self.name} #{key.inspect}")
50
+ if record = identity_map[id]
51
+ log_operation(:img, self.name, store, id)
53
52
  record
54
53
  end
55
54
  end
56
55
 
57
- def load(key, attrs)
56
+ def load(id, attrs)
58
57
  return nil if attrs.nil?
59
58
 
60
- if instance = identity_map[store_key(key)]
59
+ if instance = identity_map[id]
61
60
  instance
62
61
  else
63
62
  super.tap { |doc| doc.add_to_identity_map }
@@ -81,16 +80,14 @@ module Toy
81
80
 
82
81
  def add_to_identity_map
83
82
  return unless self.class.identity_map_on?
84
- key = store_key
85
- identity_map[key] = self
86
- logger.debug("ToyStore IMS #{self.class.name} #{key.inspect}")
83
+ identity_map[id] = self
84
+ log_operation(:ims, self.class.name, store, id)
87
85
  end
88
86
 
89
87
  def remove_from_identity_map
90
88
  return unless self.class.identity_map_on?
91
- key = store_key
92
- identity_map.delete(key)
93
- logger.debug("ToyStore IMD #{self.class.name} #{key.inspect}")
89
+ identity_map.delete(id)
90
+ log_operation(:imd, self.class.name, store, id)
94
91
  end
95
92
 
96
93
  private
data/lib/toy/logger.rb CHANGED
@@ -7,9 +7,11 @@ module Toy
7
7
  Toy.logger
8
8
  end
9
9
 
10
- def log_operation(operation, model, adapter, key, value)
11
- logger.debug("ToyStore #{operation} #{model} :#{adapter.name} #{key.inspect}")
12
- logger.debug(" #{value.inspect}")
10
+ def log_operation(operation, model, adapter, key, value=nil)
11
+ if logger.debug?
12
+ logger.debug("ToyStore #{operation.to_s.upcase} #{model} :#{adapter.name} #{key.inspect}")
13
+ logger.debug(" #{value.inspect}") unless value.nil?
14
+ end
13
15
  end
14
16
  end
15
17
 
@@ -6,7 +6,7 @@ module Toy
6
6
  def store(name=nil, client=nil, options={})
7
7
  assert_client(name, client)
8
8
  @store = Adapter[name].new(client, options) if !name.nil? && !client.nil?
9
- assert_store(name, client, 'store')
9
+ assert_store(name, client)
10
10
  @store
11
11
  end
12
12
 
@@ -14,21 +14,6 @@ module Toy
14
14
  !@store.nil?
15
15
  end
16
16
 
17
- def cache(name=nil, client=nil)
18
- assert_client(name, client)
19
- @cache = Adapter[name].new(client) if !name.nil? && !client.nil?
20
- assert_store(name, client, 'cache')
21
- @cache
22
- end
23
-
24
- def has_cache?
25
- !@cache.nil?
26
- end
27
-
28
- def store_key(id)
29
- id
30
- end
31
-
32
17
  def create(attrs={})
33
18
  new(attrs).tap { |doc| doc.save }
34
19
  end
@@ -46,8 +31,8 @@ module Toy
46
31
  raise(ArgumentError, 'Client is required') if !name.nil? && client.nil?
47
32
  end
48
33
 
49
- def assert_store(name, client, which)
50
- raise(StandardError, "No #{which} has been set") if name.nil? && client.nil? && !send(:"has_#{which}?")
34
+ def assert_store(name, client)
35
+ raise(StandardError, "No store has been set") if name.nil? && client.nil? && !has_store?
51
36
  end
52
37
  end
53
38
 
@@ -56,14 +41,6 @@ module Toy
56
41
  self.class.store
57
42
  end
58
43
 
59
- def cache
60
- self.class.cache
61
- end
62
-
63
- def store_key
64
- self.class.store_key(id)
65
- end
66
-
67
44
  def new_record?
68
45
  @_new_record == true
69
46
  end
@@ -90,10 +67,9 @@ module Toy
90
67
  end
91
68
 
92
69
  def delete
93
- key = store_key
94
70
  @_destroyed = true
95
- logger.debug("ToyStore DEL #{self.class.name} #{key.inspect}")
96
- store.delete(key)
71
+ log_operation(:del, self.class.name, store, id)
72
+ store.delete(id)
97
73
  end
98
74
 
99
75
  private
@@ -110,14 +86,10 @@ module Toy
110
86
  end
111
87
 
112
88
  def persist!
113
- key, attrs = store_key, persisted_attributes
89
+ attrs = persisted_attributes
114
90
  attrs.delete('id') # no need to persist id as that is key
115
- if self.class.has_cache?
116
- cache.write(key, attrs)
117
- log_operation('WTS', self, cache, key, attrs)
118
- end
119
- store.write(key, attrs)
120
- log_operation('SET', self, store, key, attrs)
91
+ store.write(id, attrs)
92
+ log_operation(:set, self.class.name, store, id, attrs)
121
93
  persist
122
94
  each_embedded_object { |doc| doc.send(:persist) }
123
95
  true
data/lib/toy/querying.rb CHANGED
@@ -4,24 +4,9 @@ module Toy
4
4
 
5
5
  module ClassMethods
6
6
  def get(id)
7
- key = store_key(id)
8
-
9
- if has_cache?
10
- value = cache.read(key)
11
- log_operation('RTG', self, cache, key, value)
12
- end
13
-
14
- if value.nil?
15
- value = store.read(key)
16
- log_operation('GET', self, store, key, value)
17
-
18
- if has_cache?
19
- cache.write(key, value)
20
- log_operation('RTS', self, cache, key, value)
21
- end
22
- end
23
-
24
- load(key, value)
7
+ value = store.read(id)
8
+ log_operation(:get, self, store, id, value)
9
+ load(id, value)
25
10
  end
26
11
 
27
12
  def get!(id)
@@ -41,15 +26,14 @@ module Toy
41
26
  end
42
27
 
43
28
  def key?(id)
44
- key = store_key(id)
45
- value = store.key?(key)
46
- log_operation('KEY', self, store, key, value)
29
+ value = store.key?(id)
30
+ log_operation(:key, self, store, id, value)
47
31
  value
48
32
  end
49
33
  alias :has_key? :key?
50
34
 
51
- def load(key, attrs)
52
- attrs && allocate.initialize_from_database(attrs.update('id' => key))
35
+ def load(id, attrs)
36
+ attrs && allocate.initialize_from_database(attrs.update('id' => id))
53
37
  end
54
38
  end
55
39
  end
@@ -11,12 +11,16 @@ module Toy
11
11
  module ClassMethods
12
12
  def validates_embedded(*names)
13
13
  validates_each(*names) do |record, name, value|
14
- invalid = value.compact.select { |o| !o.valid? }
14
+ invalid = value.compact.select { |obj| !obj.valid? }
15
15
  if invalid.any?
16
16
  record.errors.add(name, 'is invalid')
17
- logger.debug("ToyStore #{self.name} IEM")
18
- invalid.each do |o|
19
- logger.debug(" #{o.attributes.inspect} - #{o.errors.full_messages.inspect}")
17
+
18
+ if logger.debug?
19
+ invalid_messages = []
20
+ invalid.each do |obj|
21
+ invalid_messages << [obj.attributes, obj.errors.full_messages]
22
+ end
23
+ log_operation(:iem, self.name, store, record.id, invalid_messages)
20
24
  end
21
25
  end
22
26
  end
data/lib/toy/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Toy
2
- VERSION = "0.6.6"
2
+ VERSION = "0.7.0"
3
3
  end
data/lib/toy.rb CHANGED
@@ -38,7 +38,6 @@ module Toy
38
38
  def clear
39
39
  models.each do |model|
40
40
  model.store.clear if model.has_store?
41
- model.cache.clear if model.has_cache?
42
41
  model.identity_map.clear if model.identity_map_on?
43
42
  end
44
43
  end
@@ -2,7 +2,7 @@ module IdentityMapMatcher
2
2
  class BeInIdentityMap
3
3
  def matches?(obj)
4
4
  @obj = obj
5
- @obj.identity_map[@obj.store_key] == @obj
5
+ @obj.identity_map[@obj.id] == @obj
6
6
  end
7
7
 
8
8
  def failure_message
@@ -95,13 +95,13 @@ describe Toy::Attribute do
95
95
  end
96
96
  end
97
97
 
98
- describe "#store_key" do
98
+ describe "#persisted_name" do
99
99
  it "returns abbr if abbreviated" do
100
- Toy::Attribute.new(User, :age, String, :abbr => :a).store_key.should == 'a'
100
+ Toy::Attribute.new(User, :age, String, :abbr => :a).persisted_name.should == 'a'
101
101
  end
102
102
 
103
103
  it "returns name if not abbreviated" do
104
- Toy::Attribute.new(User, :age, String).store_key.should == 'age'
104
+ Toy::Attribute.new(User, :age, String).persisted_name.should == 'age'
105
105
  end
106
106
  end
107
107
 
@@ -325,7 +325,7 @@ describe Toy::Attributes do
325
325
 
326
326
  it "persists to store using abbreviation" do
327
327
  user = User.create(:twitter_access_token => '1234')
328
- raw = user.store.read(user.store_key)
328
+ raw = user.store.read(user.id)
329
329
  raw['tat'].should == '1234'
330
330
  raw.should_not have_key('twitter_access_token')
331
331
  end
@@ -69,7 +69,7 @@ describe Toy::IdentityMap do
69
69
  it "forces new query each time and skips the identity map" do
70
70
  user = User.create
71
71
  user.should be_in_identity_map
72
- User.store.should_receive(:read).with(user.store_key).and_return({})
72
+ User.store.should_receive(:read).with(user.id).and_return({})
73
73
  user.reload
74
74
  end
75
75
  end
@@ -117,7 +117,7 @@ describe Toy::IdentityMap do
117
117
  user = User.create
118
118
  user.should be_in_identity_map
119
119
  User.identity_map_off
120
- user.store.should_receive(:read).with(user.store_key).and_return(user.persisted_attributes)
120
+ user.store.should_receive(:read).with(user.id).and_return(user.persisted_attributes)
121
121
  User.get(user.id)
122
122
  end
123
123
  end
@@ -17,7 +17,7 @@ describe Toy::Logger do
17
17
  it "logs operation" do
18
18
  User.logger.should_receive(:debug).with('ToyStore GET User :memory "foo"')
19
19
  User.logger.should_receive(:debug).with(' "bar"')
20
- User.log_operation('GET', User, adapter, 'foo', 'bar')
20
+ User.log_operation(:get, User, adapter, 'foo', 'bar')
21
21
  end
22
22
  end
23
23
 
@@ -27,7 +27,7 @@ describe Toy::Logger do
27
27
  it "logs operation" do
28
28
  User.logger.should_receive(:debug).with('ToyStore GET User :memory "foo"')
29
29
  User.logger.should_receive(:debug).with(' "bar"')
30
- User.log_operation('GET', User, adapter, 'foo', 'bar')
30
+ User.log_operation(:get, User, adapter, 'foo', 'bar')
31
31
  end
32
32
  end
33
33
  end
@@ -36,54 +36,17 @@ describe Toy::Persistence do
36
36
  end
37
37
  end
38
38
 
39
- describe ".cache" do
40
- it "sets if arguments and reads if not" do
41
- klass.cache(:memory, {})
42
- klass.cache.should == Adapter[:memory].new({})
43
- end
44
-
45
- it "raises argument error if name provided but not client" do
46
- lambda do
47
- klass.cache(:memory)
48
- end.should raise_error(ArgumentError, 'Client is required')
49
- end
50
-
51
- it "raises argument error if no name or client provided and has not been set" do
52
- lambda do
53
- klass.cache
54
- end.should raise_error(StandardError, 'No cache has been set')
55
- end
56
- end
57
-
58
39
  describe ".has_store?" do
59
- it "returns true if cache set" do
40
+ it "returns true if store set" do
60
41
  klass.store(:memory, {})
61
42
  klass.has_store?.should be_true
62
43
  end
63
44
 
64
- it "returns false if cache not set" do
45
+ it "returns false if store not set" do
65
46
  klass.has_store?.should be_false
66
47
  end
67
48
  end
68
49
 
69
- describe ".has_cache?" do
70
- it "returns true if cache set" do
71
- klass.cache(:memory, {})
72
- klass.has_cache?.should be_true
73
- end
74
-
75
- it "returns false if cache not set" do
76
- klass.has_cache?.should be_false
77
- end
78
- end
79
-
80
- describe ".store_key" do
81
- it "returns id" do
82
- doc = User.new
83
- User.store_key(doc.id).should == doc.id
84
- end
85
- end
86
-
87
50
  describe ".create" do
88
51
  before do
89
52
  User.attribute :name, String
@@ -93,7 +56,7 @@ describe Toy::Persistence do
93
56
  let(:doc) { @doc }
94
57
 
95
58
  it "creates key in database with attributes" do
96
- User.store.read(doc.store_key).should == {
59
+ User.store.read(doc.id).should == {
97
60
  'name' => 'John',
98
61
  'age' => 50,
99
62
  }
@@ -156,13 +119,6 @@ describe Toy::Persistence do
156
119
  end
157
120
  end
158
121
 
159
- describe "#store_key" do
160
- it "returns id" do
161
- doc = User.new
162
- doc.store_key.should == doc.id
163
- end
164
- end
165
-
166
122
  describe "#new_record?" do
167
123
  it "returns true if new" do
168
124
  User.new.should be_new_record
@@ -207,15 +163,15 @@ describe Toy::Persistence do
207
163
  end
208
164
 
209
165
  it "does not persist virtual attributes" do
210
- @doc.store.read(@doc.store_key).should_not include('accepted_terms')
166
+ @doc.store.read(@doc.id).should_not include('accepted_terms')
211
167
  end
212
168
  end
213
169
 
214
170
  context "with existing record" do
215
171
  before do
216
172
  @doc = User.create(:name => 'John', :age => 28)
217
- @key = @doc.store_key
218
- @value = User.store.read(@doc.store_key)
173
+ @key = @doc.id
174
+ @value = User.store.read(@doc.id)
219
175
  @doc.name = 'Bill'
220
176
  @doc.accepted_terms = false
221
177
  @doc.save
@@ -223,15 +179,15 @@ describe Toy::Persistence do
223
179
  let(:doc) { @doc }
224
180
 
225
181
  it "stores in same key" do
226
- doc.store_key.should == @key
182
+ doc.id.should == @key
227
183
  end
228
184
 
229
185
  it "updates value in store" do
230
- User.store.read(doc.store_key).should_not == @value
186
+ User.store.read(doc.id).should_not == @value
231
187
  end
232
188
 
233
189
  it "does not persist virtual attributes" do
234
- @doc.store.read(@doc.store_key).should_not include('accepted_terms')
190
+ @doc.store.read(@doc.id).should_not include('accepted_terms')
235
191
  end
236
192
 
237
193
  it "updates the attributes in the instance" do
@@ -282,22 +238,4 @@ describe Toy::Persistence do
282
238
  doc.should be_destroyed
283
239
  end
284
240
  end
285
-
286
- describe "with cache store" do
287
- before do
288
- User.attribute(:name, String)
289
- @cache = User.cache(:memory, {})
290
- @memory = User.store(:memory, {})
291
- @user = User.create(:name => 'John')
292
- end
293
-
294
- let(:cache) { @cache }
295
- let(:memory) { @memory }
296
- let(:user) { @user }
297
-
298
- it "writes to cache and store" do
299
- cache[user.store_key].should == {'name' => 'John'}
300
- memory[user.store_key].should == {'name' => 'John'}
301
- end
302
- end
303
241
  end
@@ -103,60 +103,4 @@ describe Toy::Querying do
103
103
  doc.name.should == 'John'
104
104
  end
105
105
  end
106
-
107
- describe "with cache store" do
108
- before do
109
- @cache = User.cache(:memory, {})
110
- @memory = User.store(:memory, {})
111
- @user = User.create
112
- Toy.identity_map.clear # ensure we are just working with database
113
- end
114
-
115
- let(:cache) { @cache }
116
- let(:memory) { @memory }
117
- let(:user) { @user }
118
-
119
- describe "not found in cache or store" do
120
- before do
121
- cache.delete(user.store_key)
122
- memory.delete(user.store_key)
123
- end
124
-
125
- it "returns nil" do
126
- User.get('foo').should be_nil
127
- end
128
- end
129
-
130
- describe "not found in cache" do
131
- before do
132
- cache.delete(user.store_key)
133
- end
134
-
135
- it "returns from store" do
136
- User.get(user.id).should == user
137
- end
138
-
139
- it "populates cache" do
140
- cache.key?(user.store_key).should be_false
141
- User.get(user.id)
142
- cache.key?(user.store_key).should be_true
143
- end
144
- end
145
-
146
- describe "found in cache" do
147
- before do
148
- cache.key?(user.store_key).should be_true
149
- end
150
-
151
- it "returns from cache" do
152
- cache.should_receive(:read).with(user.store_key).and_return(user.persisted_attributes)
153
- User.get(user.id)
154
- end
155
-
156
- it "does not hit store" do
157
- memory.should_not_receive(:read)
158
- User.get(user.id)
159
- end
160
- end
161
- end
162
106
  end
data/spec/toy_spec.rb CHANGED
@@ -17,10 +17,5 @@ describe Toy do
17
17
  klass = Class.new { include Toy::Store }
18
18
  lambda { Toy.clear }.should_not raise_error
19
19
  end
20
-
21
- it "does not raise error when no cache set" do
22
- klass = Class.new { include Toy::Store }
23
- lambda { Toy.clear }.should_not raise_error
24
- end
25
20
  end
26
21
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: toystore
3
3
  version: !ruby/object:Gem::Version
4
- hash: 11
4
+ hash: 3
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
- - 6
9
- - 6
10
- version: 0.6.6
8
+ - 7
9
+ - 0
10
+ version: 0.7.0
11
11
  platform: ruby
12
12
  authors:
13
13
  - Geoffrey Dagley
@@ -109,7 +109,6 @@ files:
109
109
  - examples/models.rb
110
110
  - examples/mongo.rb
111
111
  - examples/namespacing_keys.rb
112
- - examples/read_write_caching.rb
113
112
  - examples/redis.rb
114
113
  - examples/riak.rb
115
114
  - lib/toy.rb
@@ -1,50 +0,0 @@
1
- require 'pp'
2
- require 'pathname'
3
- require 'rubygems'
4
- require 'adapter/memcached'
5
- require 'adapter/riak'
6
-
7
- root_path = Pathname(__FILE__).dirname.join('..').expand_path
8
- lib_path = root_path.join('lib')
9
- $:.unshift(lib_path)
10
- require 'toystore'
11
-
12
- class User
13
- include Toy::Store
14
- identity_map_off # turning off so we can better illustrate read/write through caching stuff
15
-
16
- store :riak, Riak::Client.new['users']
17
- cache :memcached, Memcached.new
18
-
19
- attribute :email, String
20
- end
21
-
22
- user = User.create(:email => 'nunemaker@gmail.com')
23
- # ToyStore WTS #<User:0x102810e18> :memcached "6c39dd2a-3392-11e0-9fbf-040220ce8970"
24
- # {"email"=>"nunemaker@gmail.com"}
25
- # ToyStore SET #<User:0x102810e18> :riak "6c39dd2a-3392-11e0-9fbf-040220ce8970"
26
- # {"email"=>"nunemaker@gmail.com"}
27
-
28
- user = User.get(user.id)
29
- # Get hits memcache instead of riak since it is cached
30
- # ToyStore RTG User :memcached "6c39dd2a-3392-11e0-9fbf-040220ce8970"
31
- # {"email"=>"nunemaker@gmail.com"}
32
-
33
- # delete from cache to demonstrate population on cache miss
34
- user.cache.delete(user.id)
35
-
36
- user = User.get(user.id)
37
- # Attempt read again, misses memcache, hits riak, caches in memcache
38
- # ToyStore RTG User :memcached "6c39dd2a-3392-11e0-9fbf-040220ce8970"
39
- # nil
40
- # ToyStore GET User :riak "6c39dd2a-3392-11e0-9fbf-040220ce8970"
41
- # {"email"=>"nunemaker@gmail.com"}
42
- # ToyStore RTS User :memcached "6c39dd2a-3392-11e0-9fbf-040220ce8970"
43
- # {"email"=>"nunemaker@gmail.com"}
44
-
45
- user.update_attributes(:email => 'john@orderedlist.com')
46
- # updated in memcache, then riak
47
- # ToyStore WTS #<User:0x10266f0a0> :memcached "6c39dd2a-3392-11e0-9fbf-040220ce8970"
48
- # {"email"=>"john@orderedlist.com"}
49
- # ToyStore SET #<User:0x10266f0a0> :riak "6c39dd2a-3392-11e0-9fbf-040220ce8970"
50
- # {"email"=>"john@orderedlist.com"}