machinist-caching 0.0.1
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/.gitignore +4 -0
- data/.rspec +2 -0
- data/Gemfile +8 -0
- data/Rakefile +6 -0
- data/lib/machinist/caching.rb +17 -0
- data/lib/machinist/caching/active_record.rb +16 -0
- data/lib/machinist/caching/active_record/blueprint.rb +17 -0
- data/lib/machinist/caching/machinable.rb +20 -0
- data/lib/machinist/caching/shop.rb +45 -0
- data/lib/machinist/caching/warehouse.rb +27 -0
- data/machinist-caching.gemspec +19 -0
- data/spec/machinist/caching/active_record/blueprint_spec.rb +19 -0
- data/spec/machinist/caching/machinable_spec.rb +10 -0
- data/spec/machinist/caching/shop_spec.rb +44 -0
- data/spec/machinist/caching/warehouse_spec.rb +16 -0
- data/spec/spec_helper.rb +32 -0
- metadata +110 -0
data/.gitignore
ADDED
data/.rspec
ADDED
data/Gemfile
ADDED
data/Rakefile
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'machinist'
|
2
|
+
|
3
|
+
module Machinist
|
4
|
+
module Caching
|
5
|
+
autoload :Machinable, 'machinist/caching/machinable'
|
6
|
+
autoload :Shop, 'machinist/caching/shop'
|
7
|
+
autoload :Warehouse, 'machinist/caching/warehouse'
|
8
|
+
|
9
|
+
module ActiveRecord
|
10
|
+
autoload :Blueprint, 'machinist/caching/active_record/blueprint'
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
module Machinable #:nodoc:
|
15
|
+
extend Machinist::Caching::Machinable
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'machinist/caching'
|
2
|
+
require 'machinist/active_record'
|
3
|
+
|
4
|
+
module Machinist #:nodoc:
|
5
|
+
module ActiveRecord
|
6
|
+
class Blueprint
|
7
|
+
include Machinist::Caching::ActiveRecord::Blueprint
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
module ActiveRecord #:nodoc:
|
13
|
+
class Base
|
14
|
+
extend Machinist::Caching::Machinable
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Machinist
|
2
|
+
module Caching
|
3
|
+
module ActiveRecord
|
4
|
+
module Blueprint
|
5
|
+
# Box an object for storage in the warehouse.
|
6
|
+
def box(object)
|
7
|
+
object.id
|
8
|
+
end
|
9
|
+
|
10
|
+
# Unbox an object from the warehouse.
|
11
|
+
def unbox(id)
|
12
|
+
@klass.find(id)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Machinist
|
2
|
+
module Caching
|
3
|
+
module Machinable
|
4
|
+
# Construct and save an object from a blueprint, if the class allows saving.
|
5
|
+
#
|
6
|
+
# :call-seq:
|
7
|
+
# make!([count], [blueprint_name], [attributes = {}])
|
8
|
+
#
|
9
|
+
# A cached object will be returned from the shop if possible. See
|
10
|
+
# Machinist::Caching::Shop.
|
11
|
+
#
|
12
|
+
# Arguments are the same as for make.
|
13
|
+
def make!(*args)
|
14
|
+
decode_args_to_make(*args) do |blueprint, attributes|
|
15
|
+
Shop.instance.buy(blueprint, attributes)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'singleton'
|
2
|
+
|
3
|
+
module Machinist
|
4
|
+
module Caching
|
5
|
+
# The shop takes care of caching database objects.
|
6
|
+
#
|
7
|
+
# Calling make! on a class requests objects from the shop; you don't
|
8
|
+
# normally access the shop directly.
|
9
|
+
#
|
10
|
+
# Read more about object caching on the
|
11
|
+
# wiki[http://wiki.github.com/notahat/machinist/object-caching].
|
12
|
+
class Shop
|
13
|
+
include Singleton
|
14
|
+
|
15
|
+
attr_accessor :warehouse
|
16
|
+
|
17
|
+
def initialize #:nodoc:
|
18
|
+
reset!
|
19
|
+
end
|
20
|
+
|
21
|
+
# Throw out the entire collection of cached objects.
|
22
|
+
def reset!
|
23
|
+
self.warehouse = Warehouse.new
|
24
|
+
end
|
25
|
+
|
26
|
+
# Buy a (possibly cached) object from the shop.
|
27
|
+
#
|
28
|
+
# This is just like constructing an object by calling Blueprint#make!,
|
29
|
+
# but it will return a previously cached object if one is available.
|
30
|
+
def buy(blueprint, attributes = {})
|
31
|
+
raise BlueprintCantSaveError.new(blueprint) unless blueprint.respond_to?(:make!)
|
32
|
+
|
33
|
+
cached = warehouse[blueprint, attributes]
|
34
|
+
|
35
|
+
if cached.nil?
|
36
|
+
blueprint.make!(attributes).tap do |object|
|
37
|
+
warehouse[blueprint, attributes] = blueprint.box(object)
|
38
|
+
end
|
39
|
+
else
|
40
|
+
blueprint.unbox(cached)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Machinist
|
2
|
+
module Caching
|
3
|
+
# A Warehouse is a hash supports lists as keys.
|
4
|
+
#
|
5
|
+
# It's used for storing cached objects created by Machinist::Caching::Shop.
|
6
|
+
#
|
7
|
+
# warehouse[klass, attributes] = object
|
8
|
+
# warehouse[klass, attributes] # => object
|
9
|
+
class Warehouse
|
10
|
+
attr_accessor :shelf
|
11
|
+
|
12
|
+
def initialize #:nodoc:
|
13
|
+
self.shelf = Hash.new{|hash, key| hash[key] = {}}
|
14
|
+
end
|
15
|
+
|
16
|
+
# Assign a value for the given list of keys.
|
17
|
+
def []=(klass, attributes, object)
|
18
|
+
shelf[klass][attributes] = object
|
19
|
+
end
|
20
|
+
|
21
|
+
# Return the value for the given list of keys.
|
22
|
+
def [](klass, attributes)
|
23
|
+
shelf[klass][attributes]
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
Gem::Specification.new do |s|
|
3
|
+
s.name = "machinist-caching"
|
4
|
+
s.version = "0.0.1"
|
5
|
+
s.authors = ["Tomas D'Stefano", "Gabriel Sobrinho"]
|
6
|
+
s.email = ["tomas_stefano@successoft.com", "gabriel.sobrinho@gmail.com"]
|
7
|
+
s.homepage = "https://github.com/tomas-stefano/machinist-caching"
|
8
|
+
s.summary = %q{Object caching for machinist}
|
9
|
+
s.description = %q{Object caching for machinist}
|
10
|
+
|
11
|
+
s.files = `git ls-files`.split("\n")
|
12
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
13
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
14
|
+
s.require_paths = ["lib"]
|
15
|
+
|
16
|
+
s.add_development_dependency 'rspec', '>= 2.6.0'
|
17
|
+
s.add_development_dependency 'activerecord', '>= 3.0'
|
18
|
+
s.add_development_dependency 'mysql', '>= 2.8.1'
|
19
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Machinist::Caching::ActiveRecord::Blueprint do
|
4
|
+
let :blueprint do
|
5
|
+
Machinist::ActiveRecord::Blueprint.new(Post) {}
|
6
|
+
end
|
7
|
+
|
8
|
+
let :post do
|
9
|
+
Post.make!
|
10
|
+
end
|
11
|
+
|
12
|
+
it 'should box object using id' do
|
13
|
+
blueprint.box(post).should == post.id
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'should unbox object using id' do
|
17
|
+
blueprint.unbox(post.id).should == post
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Machinist::Caching::Shop do
|
4
|
+
let :shop do
|
5
|
+
Machinist::Caching::Shop.instance
|
6
|
+
end
|
7
|
+
|
8
|
+
it 'should cache an object' do
|
9
|
+
blueprint = Machinist::ActiveRecord::Blueprint.new(Post) {}
|
10
|
+
|
11
|
+
object_a = shop.buy(blueprint)
|
12
|
+
object_b = shop.buy(blueprint)
|
13
|
+
|
14
|
+
object_a.should == object_b
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'should cache an object with attributes' do
|
18
|
+
blueprint = Machinist::ActiveRecord::Blueprint.new(Post) {}
|
19
|
+
|
20
|
+
object_a = shop.buy(blueprint, :title => 'Lorem ipsum')
|
21
|
+
object_b = shop.buy(blueprint, :title => 'Lorem ipsum')
|
22
|
+
|
23
|
+
object_a.should == object_b
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'should not confuse objects with different blueprints' do
|
27
|
+
blueprint_a = Machinist::ActiveRecord::Blueprint.new(Post) {}
|
28
|
+
blueprint_b = Machinist::ActiveRecord::Blueprint.new(Post) {}
|
29
|
+
|
30
|
+
object_a = shop.buy(blueprint_a, :title => 'Lorem ipsum')
|
31
|
+
object_b = shop.buy(blueprint_b, :title => 'Lorem ipsum')
|
32
|
+
|
33
|
+
object_a.should_not == object_b
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'should not confuse objects with same blueprint but different attributes' do
|
37
|
+
blueprint = Machinist::ActiveRecord::Blueprint.new(Post) {}
|
38
|
+
|
39
|
+
object_a = shop.buy(blueprint, :title => 'Lorem ipsum')
|
40
|
+
object_b = shop.buy(blueprint, :title => 'Lorem ipsum dolor sit amet')
|
41
|
+
|
42
|
+
object_a.should_not == object_b
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Machinist::Caching::Warehouse do
|
4
|
+
let :warehouse do
|
5
|
+
Machinist::Caching::Warehouse.new
|
6
|
+
end
|
7
|
+
|
8
|
+
it 'should return nil for a new key' do
|
9
|
+
warehouse['klass', 'attributes'].should == nil
|
10
|
+
end
|
11
|
+
|
12
|
+
it 'should store and retrieve values' do
|
13
|
+
warehouse['klass', 'attributes'] = 'object'
|
14
|
+
warehouse['klass', 'attributes'].should == 'object'
|
15
|
+
end
|
16
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'rspec'
|
2
|
+
require 'machinist/caching/active_record'
|
3
|
+
|
4
|
+
ActiveRecord::Base.establish_connection(
|
5
|
+
:adapter => "mysql",
|
6
|
+
:database => "machinist",
|
7
|
+
:username => "root",
|
8
|
+
:password => ""
|
9
|
+
)
|
10
|
+
|
11
|
+
ActiveRecord::Migration.verbose = false
|
12
|
+
|
13
|
+
ActiveRecord::Schema.define(:version => 0) do
|
14
|
+
create_table :posts, :force => true do |t|
|
15
|
+
t.column :title, :string
|
16
|
+
t.column :body, :text
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
class Post < ActiveRecord::Base
|
21
|
+
end
|
22
|
+
|
23
|
+
Post.blueprint do
|
24
|
+
title { 'Lorem ipsum' }
|
25
|
+
body { 'Lorem ipsum dolor sit amet, consectetuer adipiscing elit.' }
|
26
|
+
end
|
27
|
+
|
28
|
+
RSpec.configure do |config|
|
29
|
+
config.before do
|
30
|
+
Machinist::Caching::Shop.instance.reset!
|
31
|
+
end
|
32
|
+
end
|
metadata
ADDED
@@ -0,0 +1,110 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: machinist-caching
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease:
|
5
|
+
version: 0.0.1
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Tomas D'Stefano
|
9
|
+
- Gabriel Sobrinho
|
10
|
+
autorequire:
|
11
|
+
bindir: bin
|
12
|
+
cert_chain: []
|
13
|
+
|
14
|
+
date: 2011-07-14 00:00:00 -03:00
|
15
|
+
default_executable:
|
16
|
+
dependencies:
|
17
|
+
- !ruby/object:Gem::Dependency
|
18
|
+
name: rspec
|
19
|
+
prerelease: false
|
20
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
21
|
+
none: false
|
22
|
+
requirements:
|
23
|
+
- - ">="
|
24
|
+
- !ruby/object:Gem::Version
|
25
|
+
version: 2.6.0
|
26
|
+
type: :development
|
27
|
+
version_requirements: *id001
|
28
|
+
- !ruby/object:Gem::Dependency
|
29
|
+
name: activerecord
|
30
|
+
prerelease: false
|
31
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
32
|
+
none: false
|
33
|
+
requirements:
|
34
|
+
- - ">="
|
35
|
+
- !ruby/object:Gem::Version
|
36
|
+
version: "3.0"
|
37
|
+
type: :development
|
38
|
+
version_requirements: *id002
|
39
|
+
- !ruby/object:Gem::Dependency
|
40
|
+
name: mysql
|
41
|
+
prerelease: false
|
42
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
43
|
+
none: false
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: 2.8.1
|
48
|
+
type: :development
|
49
|
+
version_requirements: *id003
|
50
|
+
description: Object caching for machinist
|
51
|
+
email:
|
52
|
+
- tomas_stefano@successoft.com
|
53
|
+
- gabriel.sobrinho@gmail.com
|
54
|
+
executables: []
|
55
|
+
|
56
|
+
extensions: []
|
57
|
+
|
58
|
+
extra_rdoc_files: []
|
59
|
+
|
60
|
+
files:
|
61
|
+
- .gitignore
|
62
|
+
- .rspec
|
63
|
+
- Gemfile
|
64
|
+
- Rakefile
|
65
|
+
- lib/machinist/caching.rb
|
66
|
+
- lib/machinist/caching/active_record.rb
|
67
|
+
- lib/machinist/caching/active_record/blueprint.rb
|
68
|
+
- lib/machinist/caching/machinable.rb
|
69
|
+
- lib/machinist/caching/shop.rb
|
70
|
+
- lib/machinist/caching/warehouse.rb
|
71
|
+
- machinist-caching.gemspec
|
72
|
+
- spec/machinist/caching/active_record/blueprint_spec.rb
|
73
|
+
- spec/machinist/caching/machinable_spec.rb
|
74
|
+
- spec/machinist/caching/shop_spec.rb
|
75
|
+
- spec/machinist/caching/warehouse_spec.rb
|
76
|
+
- spec/spec_helper.rb
|
77
|
+
has_rdoc: true
|
78
|
+
homepage: https://github.com/tomas-stefano/machinist-caching
|
79
|
+
licenses: []
|
80
|
+
|
81
|
+
post_install_message:
|
82
|
+
rdoc_options: []
|
83
|
+
|
84
|
+
require_paths:
|
85
|
+
- lib
|
86
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
87
|
+
none: false
|
88
|
+
requirements:
|
89
|
+
- - ">="
|
90
|
+
- !ruby/object:Gem::Version
|
91
|
+
version: "0"
|
92
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
93
|
+
none: false
|
94
|
+
requirements:
|
95
|
+
- - ">="
|
96
|
+
- !ruby/object:Gem::Version
|
97
|
+
version: "0"
|
98
|
+
requirements: []
|
99
|
+
|
100
|
+
rubyforge_project:
|
101
|
+
rubygems_version: 1.5.2
|
102
|
+
signing_key:
|
103
|
+
specification_version: 3
|
104
|
+
summary: Object caching for machinist
|
105
|
+
test_files:
|
106
|
+
- spec/machinist/caching/active_record/blueprint_spec.rb
|
107
|
+
- spec/machinist/caching/machinable_spec.rb
|
108
|
+
- spec/machinist/caching/shop_spec.rb
|
109
|
+
- spec/machinist/caching/warehouse_spec.rb
|
110
|
+
- spec/spec_helper.rb
|