toystore 0.7.0 → 0.8.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +1 -1
- data/examples/mongo.rb +0 -1
- data/lib/toy/attributes.rb +2 -1
- data/lib/toy/identity.rb +8 -12
- data/lib/toy/version.rb +1 -1
- data/perf/reads.rb +45 -0
- data/perf/writes.rb +33 -0
- data/spec/toy/attributes_spec.rb +21 -0
- data/spec/toy/identity/uuid_key_factory_spec.rb +1 -1
- data/spec/toy/identity_spec.rb +2 -6
- data/spec/toy/reference_spec.rb +0 -11
- metadata +6 -8
- data/examples/changing_key_factory.rb +0 -16
- data/lib/toy/identity/object_id_key_factory.rb +0 -26
- data/spec/toy/identity/object_id_key_factory_spec.rb +0 -40
data/README.rdoc
CHANGED
@@ -10,7 +10,7 @@ https://groups.google.com/forum/#!forum/toystoreadapter
|
|
10
10
|
|
11
11
|
== Identity Map
|
12
12
|
|
13
|
-
By default, Toystore has identity map turned on. It assumes that any Toystore model has a unique id across all models. This means you either need to use the default uuid id's
|
13
|
+
By default, Toystore has identity map turned on. It assumes that any Toystore model has a unique id across all models. This means you either need to use the default uuid id's or create your own key factory that namespaces to model (see examples).
|
14
14
|
|
15
15
|
You also need to clear the map before each request. For this, there is a provided piece of middleware that you can use.
|
16
16
|
|
data/examples/mongo.rb
CHANGED
data/lib/toy/attributes.rb
CHANGED
@@ -99,6 +99,7 @@ module Toy
|
|
99
99
|
|
100
100
|
private
|
101
101
|
def read_attribute(key)
|
102
|
+
@attributes ||= {}
|
102
103
|
@attributes[key.to_s]
|
103
104
|
end
|
104
105
|
|
@@ -127,7 +128,7 @@ module Toy
|
|
127
128
|
end
|
128
129
|
|
129
130
|
def initialize_attributes_with_defaults
|
130
|
-
@attributes
|
131
|
+
@attributes ||= {}
|
131
132
|
self.class.defaulted_attributes.each do |attribute|
|
132
133
|
@attributes[attribute.name.to_s] = attribute.default
|
133
134
|
end
|
data/lib/toy/identity.rb
CHANGED
@@ -8,20 +8,16 @@ module Toy
|
|
8
8
|
|
9
9
|
module ClassMethods
|
10
10
|
def key(name_or_factory = :uuid)
|
11
|
-
@key_factory =
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
ObjectIdKeyFactory.new
|
11
|
+
@key_factory = if name_or_factory == :uuid
|
12
|
+
UUIDKeyFactory.new
|
13
|
+
else
|
14
|
+
if name_or_factory.respond_to?(:next_key) && name_or_factory.respond_to?(:key_type)
|
15
|
+
name_or_factory
|
17
16
|
else
|
18
|
-
|
19
|
-
name_or_factory.respond_to?(:key_type)
|
20
|
-
name_or_factory
|
21
|
-
else
|
22
|
-
raise InvalidKeyFactory.new(name_or_factory)
|
23
|
-
end
|
17
|
+
raise InvalidKeyFactory.new(name_or_factory)
|
24
18
|
end
|
19
|
+
end
|
20
|
+
|
25
21
|
attribute :id, @key_factory.key_type
|
26
22
|
@key_factory
|
27
23
|
end
|
data/lib/toy/version.rb
CHANGED
data/perf/reads.rb
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
# require 'perftools'
|
2
|
+
require 'pp'
|
3
|
+
require 'logger'
|
4
|
+
require 'benchmark'
|
5
|
+
require 'rubygems'
|
6
|
+
|
7
|
+
$:.unshift File.expand_path(File.dirname(__FILE__) + '/../lib')
|
8
|
+
require 'toystore'
|
9
|
+
require 'adapter/memory'
|
10
|
+
|
11
|
+
Toy.logger = ::Logger.new(STDOUT).tap { |log| log.level = ::Logger::INFO }
|
12
|
+
|
13
|
+
class User
|
14
|
+
include Toy::Store
|
15
|
+
identity_map_off
|
16
|
+
store(:memory, {})
|
17
|
+
attribute :name, String
|
18
|
+
end
|
19
|
+
|
20
|
+
user = User.create(:name => 'John')
|
21
|
+
id = user.id
|
22
|
+
times = 10_000
|
23
|
+
|
24
|
+
client_result = Benchmark.realtime {
|
25
|
+
times.times { User.store.decode(User.store.client[User.store.key_for(id)]) }
|
26
|
+
}
|
27
|
+
|
28
|
+
store_result = Benchmark.realtime {
|
29
|
+
times.times { User.get(id) }
|
30
|
+
}
|
31
|
+
|
32
|
+
puts 'Client', client_result
|
33
|
+
puts 'Toystore', store_result
|
34
|
+
puts 'Ratio', store_result / client_result
|
35
|
+
|
36
|
+
# PerfTools::CpuProfiler.start('prof_client') do
|
37
|
+
# times.times{ User.store.decode(User.store.client[User.store.key_for(id)]) }
|
38
|
+
# end
|
39
|
+
|
40
|
+
# PerfTools::CpuProfiler.start('prof_reads') do
|
41
|
+
# times.times{ User.get(id) }
|
42
|
+
# end
|
43
|
+
|
44
|
+
# system('pprof.rb --gif --ignore=Collection#find_one prof_reads > prof_reads.gif')
|
45
|
+
# system('open prof_reads.gif')
|
data/perf/writes.rb
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
# require 'perftools'
|
2
|
+
require 'pp'
|
3
|
+
require 'logger'
|
4
|
+
require 'benchmark'
|
5
|
+
require 'rubygems'
|
6
|
+
|
7
|
+
$:.unshift File.expand_path(File.dirname(__FILE__) + '/../lib')
|
8
|
+
require 'toystore'
|
9
|
+
require 'adapter/memory'
|
10
|
+
|
11
|
+
Toy.logger = ::Logger.new(STDOUT).tap { |log| log.level = ::Logger::INFO }
|
12
|
+
|
13
|
+
class User
|
14
|
+
include Toy::Store
|
15
|
+
identity_map_off
|
16
|
+
store(:memory, {})
|
17
|
+
end
|
18
|
+
|
19
|
+
times = 10_000
|
20
|
+
user = User.new
|
21
|
+
id = user.id
|
22
|
+
attrs = user.persisted_attributes
|
23
|
+
|
24
|
+
client_result = Benchmark.realtime {
|
25
|
+
times.times { User.store.write(id, attrs) }
|
26
|
+
}
|
27
|
+
store_result = Benchmark.realtime {
|
28
|
+
times.times { User.create }
|
29
|
+
}
|
30
|
+
|
31
|
+
puts 'Client', client_result
|
32
|
+
puts 'Toystore', store_result
|
33
|
+
puts 'Ratio', store_result / client_result
|
data/spec/toy/attributes_spec.rb
CHANGED
@@ -423,4 +423,25 @@ describe Toy::Attributes do
|
|
423
423
|
User.new.skills.should == []
|
424
424
|
end
|
425
425
|
end
|
426
|
+
|
427
|
+
# https://github.com/newtoy/toystore/issues/13
|
428
|
+
describe "Overriding initialize and setting an attribute before calling super" do
|
429
|
+
before do
|
430
|
+
User.attribute(:name, String)
|
431
|
+
User.class_eval do
|
432
|
+
def initialize(*)
|
433
|
+
self.name = 'John'
|
434
|
+
super
|
435
|
+
end
|
436
|
+
end
|
437
|
+
end
|
438
|
+
|
439
|
+
it "does not throw error" do
|
440
|
+
lambda { User.new }.should_not raise_error
|
441
|
+
end
|
442
|
+
|
443
|
+
it "sets value" do
|
444
|
+
User.new.name.should == 'John'
|
445
|
+
end
|
446
|
+
end
|
426
447
|
end
|
data/spec/toy/identity_spec.rb
CHANGED
@@ -8,21 +8,17 @@ describe Toy::Identity do
|
|
8
8
|
User.key(:uuid).should be_instance_of(Toy::Identity::UUIDKeyFactory)
|
9
9
|
end
|
10
10
|
|
11
|
-
it "should use ObjectIdKeyFactory if :object_id" do
|
12
|
-
User.key(:object_id).should be_instance_of(Toy::Identity::ObjectIdKeyFactory)
|
13
|
-
end
|
14
|
-
|
15
11
|
it "should set key factory passed in factory" do
|
16
12
|
factory = Toy::Identity::UUIDKeyFactory.new
|
17
13
|
User.key(factory).should == factory
|
18
14
|
end
|
19
15
|
|
20
16
|
it "should use Toy.key_factory by default" do
|
21
|
-
key_factory = Toy::Identity::
|
17
|
+
key_factory = Toy::Identity::UUIDKeyFactory.new
|
22
18
|
Toy.key_factory = key_factory
|
23
19
|
Class.new do
|
24
20
|
include Toy::Store
|
25
|
-
end.key_factory.should be_instance_of(Toy::Identity::
|
21
|
+
end.key_factory.should be_instance_of(Toy::Identity::UUIDKeyFactory)
|
26
22
|
end
|
27
23
|
end
|
28
24
|
|
data/spec/toy/reference_spec.rb
CHANGED
@@ -49,17 +49,6 @@ describe Toy::Reference do
|
|
49
49
|
Game.new.should respond_to(:user=)
|
50
50
|
end
|
51
51
|
|
52
|
-
describe "with object_id key" do
|
53
|
-
before(:each) do
|
54
|
-
User.key(:object_id)
|
55
|
-
@reference = Game.reference(:user)
|
56
|
-
end
|
57
|
-
|
58
|
-
it "sets type to BSON::ObjectId" do
|
59
|
-
Game.attributes['user_id'].type.should be(BSON::ObjectId)
|
60
|
-
end
|
61
|
-
end
|
62
|
-
|
63
52
|
describe "#eql?" do
|
64
53
|
it "returns true if same class, model, and name" do
|
65
54
|
reference.should eql(reference)
|
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:
|
4
|
+
hash: 63
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
|
-
-
|
8
|
+
- 8
|
9
9
|
- 0
|
10
|
-
version: 0.
|
10
|
+
version: 0.8.0
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Geoffrey Dagley
|
@@ -16,7 +16,7 @@ autorequire:
|
|
16
16
|
bindir: bin
|
17
17
|
cert_chain: []
|
18
18
|
|
19
|
-
date: 2011-05-
|
19
|
+
date: 2011-05-28 00:00:00 Z
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
22
22
|
name: adapter
|
@@ -102,7 +102,6 @@ files:
|
|
102
102
|
- Rakefile
|
103
103
|
- examples/attributes_abbreviation.rb
|
104
104
|
- examples/attributes_virtual.rb
|
105
|
-
- examples/changing_key_factory.rb
|
106
105
|
- examples/identity_map.rb
|
107
106
|
- examples/memcached.rb
|
108
107
|
- examples/memory.rb
|
@@ -137,7 +136,6 @@ files:
|
|
137
136
|
- lib/toy/extensions/time.rb
|
138
137
|
- lib/toy/identity.rb
|
139
138
|
- lib/toy/identity/abstract_key_factory.rb
|
140
|
-
- lib/toy/identity/object_id_key_factory.rb
|
141
139
|
- lib/toy/identity/uuid_key_factory.rb
|
142
140
|
- lib/toy/identity_map.rb
|
143
141
|
- lib/toy/index.rb
|
@@ -162,6 +160,8 @@ files:
|
|
162
160
|
- lib/toy/validations.rb
|
163
161
|
- lib/toy/version.rb
|
164
162
|
- lib/toystore.rb
|
163
|
+
- perf/reads.rb
|
164
|
+
- perf/writes.rb
|
165
165
|
- spec/helper.rb
|
166
166
|
- spec/spec.opts
|
167
167
|
- spec/support/constants.rb
|
@@ -189,7 +189,6 @@ files:
|
|
189
189
|
- spec/toy/extensions/string_spec.rb
|
190
190
|
- spec/toy/extensions/time_spec.rb
|
191
191
|
- spec/toy/identity/abstract_key_factory_spec.rb
|
192
|
-
- spec/toy/identity/object_id_key_factory_spec.rb
|
193
192
|
- spec/toy/identity/uuid_key_factory_spec.rb
|
194
193
|
- spec/toy/identity_map_spec.rb
|
195
194
|
- spec/toy/identity_spec.rb
|
@@ -275,7 +274,6 @@ test_files:
|
|
275
274
|
- spec/toy/extensions/string_spec.rb
|
276
275
|
- spec/toy/extensions/time_spec.rb
|
277
276
|
- spec/toy/identity/abstract_key_factory_spec.rb
|
278
|
-
- spec/toy/identity/object_id_key_factory_spec.rb
|
279
277
|
- spec/toy/identity/uuid_key_factory_spec.rb
|
280
278
|
- spec/toy/identity_map_spec.rb
|
281
279
|
- spec/toy/identity_spec.rb
|
@@ -1,16 +0,0 @@
|
|
1
|
-
require 'pp'
|
2
|
-
require 'rubygems'
|
3
|
-
require 'pathname'
|
4
|
-
|
5
|
-
root_path = Pathname(__FILE__).dirname.join('..').expand_path
|
6
|
-
lib_path = root_path.join('lib')
|
7
|
-
$:.unshift(lib_path)
|
8
|
-
|
9
|
-
require 'toystore'
|
10
|
-
|
11
|
-
class User
|
12
|
-
include Toy::Store
|
13
|
-
key :object_id
|
14
|
-
end
|
15
|
-
|
16
|
-
puts User.new.id # BSON::ObjectId ...
|
@@ -1,26 +0,0 @@
|
|
1
|
-
require 'bson'
|
2
|
-
|
3
|
-
module Toy
|
4
|
-
module Identity
|
5
|
-
class ObjectIdKeyFactory < AbstractKeyFactory
|
6
|
-
def key_type
|
7
|
-
BSON::ObjectId
|
8
|
-
end
|
9
|
-
|
10
|
-
def next_key(object)
|
11
|
-
BSON::ObjectId.new
|
12
|
-
end
|
13
|
-
end
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
|
-
class BSON::ObjectId
|
18
|
-
def self.to_store(value, *)
|
19
|
-
return value if value.is_a?(BSON::ObjectId)
|
20
|
-
BSON::ObjectId.from_string(value.to_s)
|
21
|
-
end
|
22
|
-
|
23
|
-
def self.from_store(value, *args)
|
24
|
-
to_store(value, *args)
|
25
|
-
end
|
26
|
-
end
|
@@ -1,40 +0,0 @@
|
|
1
|
-
require 'helper'
|
2
|
-
require 'toy/identity/object_id_key_factory'
|
3
|
-
|
4
|
-
describe Toy::Identity::ObjectIdKeyFactory do
|
5
|
-
uses_constants('User')
|
6
|
-
|
7
|
-
it "should use BSON::ObjectId as key_type" do
|
8
|
-
Toy::Identity::ObjectIdKeyFactory.new.key_type.should be(BSON::ObjectId)
|
9
|
-
end
|
10
|
-
|
11
|
-
it "should use object id for next key" do
|
12
|
-
key = Toy::Identity::ObjectIdKeyFactory.new.next_key(nil)
|
13
|
-
key.should be_instance_of(BSON::ObjectId)
|
14
|
-
end
|
15
|
-
|
16
|
-
describe "Declaring key to be object_id" do
|
17
|
-
before(:each) do
|
18
|
-
User.key(:object_id)
|
19
|
-
User.attribute(:name, String)
|
20
|
-
end
|
21
|
-
|
22
|
-
it "returns BSON::ObjectId as .key_type" do
|
23
|
-
User.key_type.should be(BSON::ObjectId)
|
24
|
-
end
|
25
|
-
|
26
|
-
it "sets id attribute to BSON::ObjectId type" do
|
27
|
-
User.attributes['id'].type.should be(BSON::ObjectId)
|
28
|
-
end
|
29
|
-
|
30
|
-
it "correctly stores id in database" do
|
31
|
-
user = User.create(:name => 'John')
|
32
|
-
user.id.should be_instance_of(BSON::ObjectId)
|
33
|
-
# key_for in memory adapter marshals non symbol/string keys
|
34
|
-
# so we have to unmarshal to get the key type
|
35
|
-
key = Marshal.load(user.store.client.keys.first)
|
36
|
-
key.should be_instance_of(BSON::ObjectId)
|
37
|
-
user.id.should == key
|
38
|
-
end
|
39
|
-
end
|
40
|
-
end
|