toystore 0.6.6 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
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"}