merb-cache 0.9.7 → 0.9.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.
- data/LICENSE +2 -2
- data/README +207 -143
- data/Rakefile +55 -10
- data/TODO +0 -2
- data/lib/merb-cache/cache.rb +84 -0
- data/lib/merb-cache/core_ext/enumerable.rb +9 -0
- data/lib/merb-cache/core_ext/hash.rb +20 -0
- data/lib/merb-cache/merb_ext/controller.rb +167 -0
- data/lib/merb-cache/stores/fundamental/abstract_store.rb +101 -0
- data/lib/merb-cache/stores/fundamental/file_store.rb +112 -0
- data/lib/merb-cache/stores/fundamental/memcached_store.rb +112 -0
- data/lib/merb-cache/stores/strategy/abstract_strategy_store.rb +123 -0
- data/lib/merb-cache/stores/strategy/action_store.rb +56 -0
- data/lib/merb-cache/stores/strategy/adhoc_store.rb +69 -0
- data/lib/merb-cache/stores/strategy/gzip_store.rb +63 -0
- data/lib/merb-cache/stores/strategy/page_store.rb +64 -0
- data/lib/merb-cache/stores/strategy/sha1_store.rb +62 -0
- data/lib/merb-cache.rb +8 -7
- data/spec/merb-cache/cache_spec.rb +88 -0
- data/spec/merb-cache/core_ext/enumerable_spec.rb +22 -0
- data/spec/merb-cache/core_ext/hash_spec.rb +20 -0
- data/spec/merb-cache/merb_ext/controller_spec.rb +284 -0
- data/spec/merb-cache/stores/fundamental/abstract_store_spec.rb +166 -0
- data/spec/merb-cache/stores/fundamental/file_store_spec.rb +186 -0
- data/spec/merb-cache/stores/fundamental/memcached_store_spec.rb +243 -0
- data/spec/merb-cache/stores/strategy/abstract_strategy_store_spec.rb +78 -0
- data/spec/merb-cache/stores/strategy/action_store_spec.rb +189 -0
- data/spec/merb-cache/stores/strategy/adhoc_store_spec.rb +225 -0
- data/spec/merb-cache/stores/strategy/gzip_store_spec.rb +51 -0
- data/spec/merb-cache/stores/strategy/page_store_spec.rb +111 -0
- data/spec/merb-cache/stores/strategy/sha1_store_spec.rb +75 -0
- data/spec/spec_helper.rb +69 -72
- metadata +42 -31
- data/lib/merb-cache/cache-action.rb +0 -144
- data/lib/merb-cache/cache-fragment.rb +0 -95
- data/lib/merb-cache/cache-page.rb +0 -203
- data/lib/merb-cache/cache-store/database-activerecord.rb +0 -88
- data/lib/merb-cache/cache-store/database-datamapper.rb +0 -79
- data/lib/merb-cache/cache-store/database-sequel.rb +0 -78
- data/lib/merb-cache/cache-store/database.rb +0 -144
- data/lib/merb-cache/cache-store/dummy.rb +0 -106
- data/lib/merb-cache/cache-store/file.rb +0 -194
- data/lib/merb-cache/cache-store/memcache.rb +0 -199
- data/lib/merb-cache/cache-store/memory.rb +0 -168
- data/lib/merb-cache/merb-cache.rb +0 -165
- data/lib/merb-cache/merbtasks.rb +0 -6
- data/spec/config/database.yml +0 -14
- data/spec/controller.rb +0 -101
- data/spec/log/merb_test.log +0 -433
- data/spec/merb-cache-action_spec.rb +0 -162
- data/spec/merb-cache-fragment_spec.rb +0 -100
- data/spec/merb-cache-page_spec.rb +0 -150
- data/spec/merb-cache_spec.rb +0 -15
- data/spec/views/cache_controller/action1.html.erb +0 -4
- data/spec/views/cache_controller/action2.html.haml +0 -4
@@ -1,203 +0,0 @@
|
|
1
|
-
class Merb::Cache
|
2
|
-
cattr_accessor :cached_pages
|
3
|
-
self.cached_pages = {}
|
4
|
-
end
|
5
|
-
|
6
|
-
module Merb::Cache::ControllerClassMethods
|
7
|
-
# Mixed in Merb::Controller. Provides class methods related to page caching
|
8
|
-
# Page caching is mostly action caching with file backend using its own output directory of .html files
|
9
|
-
|
10
|
-
# Register the action for page caching
|
11
|
-
#
|
12
|
-
# ==== Parameters
|
13
|
-
# action<Symbol>:: The name of the action to register
|
14
|
-
# from_now<~minutes>::
|
15
|
-
# The number of minutes (from now) the cache should persist
|
16
|
-
#
|
17
|
-
# ==== Examples
|
18
|
-
# cache_page :mostly_static
|
19
|
-
# cache_page :barely_dynamic, 10
|
20
|
-
def cache_page(action, from_now = nil)
|
21
|
-
cache_pages([action, from_now])
|
22
|
-
end
|
23
|
-
|
24
|
-
# Register actions for page caching (before and after filters)
|
25
|
-
#
|
26
|
-
# ==== Parameter
|
27
|
-
# pages<Symbol,Array[Symbol,~minutes]>:: See #cache_page
|
28
|
-
#
|
29
|
-
# ==== Example
|
30
|
-
# cache_pages :mostly_static, [:barely_dynamic, 10]
|
31
|
-
def cache_pages(*pages)
|
32
|
-
if pages.any? && !Merb::Cache.cached_pages.key?(controller_name)
|
33
|
-
before(:cache_page_before)
|
34
|
-
after(:cache_page_after)
|
35
|
-
end
|
36
|
-
pages.each do |action, from_now|
|
37
|
-
_pages = Merb::Cache.cached_pages[controller_name] ||= {}
|
38
|
-
_pages[action] = [from_now, 0]
|
39
|
-
end
|
40
|
-
true
|
41
|
-
end
|
42
|
-
end
|
43
|
-
|
44
|
-
module Merb::Cache::ControllerInstanceMethods
|
45
|
-
# Mixed in Merb::Controller. Provides methods related to page caching
|
46
|
-
|
47
|
-
DEFAULT_PAGE_EXTENSION = 'html'
|
48
|
-
|
49
|
-
# Checks whether a cache entry exists
|
50
|
-
#
|
51
|
-
# ==== Parameter
|
52
|
-
# options<String,Hash>:: The options that will be passed to #key_for
|
53
|
-
#
|
54
|
-
# ==== Returns
|
55
|
-
# true if the cache entry exists, false otherwise
|
56
|
-
#
|
57
|
-
# ==== Example
|
58
|
-
# cached_page?(:action => 'show', :params => [params[:page]])
|
59
|
-
# cached_page?(:action => 'show', :extension => 'js')
|
60
|
-
def cached_page?(options)
|
61
|
-
key = Merb::Controller._cache.key_for(options, controller_name, true)
|
62
|
-
extension = options[:extension] || DEFAULT_PAGE_EXTENSION
|
63
|
-
File.file?(Merb::Controller._cache.config[:cache_html_directory] / "#{key}.#{extension}")
|
64
|
-
end
|
65
|
-
|
66
|
-
# Expires the page identified by the key computed after the parameters
|
67
|
-
#
|
68
|
-
# ==== Parameter
|
69
|
-
# options<String,Hash>:: The options that will be passed to #expire_key_for
|
70
|
-
#
|
71
|
-
# ==== Examples (See Merb::Cache#expire_key_for for more options)
|
72
|
-
# # will expire path/to/page/cache/news/show/1.html
|
73
|
-
# expire_page(:key => url(:news,News.find(1)))
|
74
|
-
#
|
75
|
-
# # will expire path/to/page/cache/news/show.html
|
76
|
-
# expire_page(:action => 'show', :controller => 'news')
|
77
|
-
#
|
78
|
-
# # will expire path/to/page/cache/news/show*
|
79
|
-
# expire_page(:action => 'show', :match => true)
|
80
|
-
#
|
81
|
-
# # will expire path/to/page/cache/news/show.js
|
82
|
-
# expire_page(:action => 'show', :extension => 'js')
|
83
|
-
def expire_page(options)
|
84
|
-
config_dir = Merb::Controller._cache.config[:cache_html_directory]
|
85
|
-
Merb::Controller._cache.expire_key_for(options, controller_name, true) do |key, match|
|
86
|
-
if match
|
87
|
-
files = Dir.glob(config_dir / "#{key}*")
|
88
|
-
else
|
89
|
-
extension = options[:extension] || DEFAULT_PAGE_EXTENSION
|
90
|
-
files = config_dir / "#{key}.#{extension}"
|
91
|
-
end
|
92
|
-
FileUtils.rm_rf(files)
|
93
|
-
end
|
94
|
-
true
|
95
|
-
end
|
96
|
-
|
97
|
-
# Expires all the pages stored in config[:cache_html_directory]
|
98
|
-
def expire_all_pages
|
99
|
-
FileUtils.rm_rf(Dir.glob(Merb::Controller._cache.config[:cache_html_directory] / "*"))
|
100
|
-
end
|
101
|
-
|
102
|
-
# You can call this method if you need to prevent caching the page
|
103
|
-
# after it has been rendered.
|
104
|
-
def abort_cache_page
|
105
|
-
@capture_page = false
|
106
|
-
end
|
107
|
-
|
108
|
-
private
|
109
|
-
|
110
|
-
# Called by the before and after filters. Stores or recalls a cache entry.
|
111
|
-
# The name used for the cache file is based on request.path
|
112
|
-
# If the name ends with "/" then it is removed
|
113
|
-
# If the name is "/" then it will be replaced by "index"
|
114
|
-
#
|
115
|
-
# ==== Parameters
|
116
|
-
# data<String>:: the data to put in cache
|
117
|
-
#
|
118
|
-
# ==== Examples
|
119
|
-
# All the file are written to config[:cache_html_directory]
|
120
|
-
# If request.path is "/", the name will be "/index.html"
|
121
|
-
# If request.path is "/news/show/1", the name will be "/news/show/1.html"
|
122
|
-
# If request.path is "/news/show/", the name will be "/news/show.html"
|
123
|
-
# If request.path is "/news/styles.css", the name will be "/news/styles.css"
|
124
|
-
def _cache_page(data = nil)
|
125
|
-
return if Merb::Controller._cache.config[:disable_page_caching]
|
126
|
-
controller = controller_name
|
127
|
-
action = action_name.to_sym
|
128
|
-
pages = Merb::Controller._cache.cached_pages[controller]
|
129
|
-
return unless pages && pages.key?(action)
|
130
|
-
path = request.path.chomp("/")
|
131
|
-
path = "index" if path.empty?
|
132
|
-
no_format = params[:format].nil? || params[:format].empty?
|
133
|
-
ext = "." + (no_format ? DEFAULT_PAGE_EXTENSION : params[:format])
|
134
|
-
ext = nil if File.extname(path) == ext
|
135
|
-
cache_file = Merb::Controller._cache.config[:cache_html_directory] / "#{path}#{ext}"
|
136
|
-
if data
|
137
|
-
cache_directory = File.dirname(cache_file)
|
138
|
-
FileUtils.mkdir_p(cache_directory)
|
139
|
-
_expire_in = pages[action][0]
|
140
|
-
pages[action][1] = _expire_in.minutes.from_now unless _expire_in.nil?
|
141
|
-
cache_write_page(cache_file, data)
|
142
|
-
Merb.logger.info("cache: set (#{path})")
|
143
|
-
else
|
144
|
-
@capture_page = false
|
145
|
-
if File.file?(cache_file)
|
146
|
-
_data = cache_read_page(cache_file)
|
147
|
-
_expire_in, _expire_at = pages[action]
|
148
|
-
if _expire_in.nil? || Time.now.to_i < _expire_at.to_i
|
149
|
-
Merb.logger.info("cache: hit (#{path})")
|
150
|
-
throw(:halt, _data)
|
151
|
-
end
|
152
|
-
FileUtils.rm_f(cache_file)
|
153
|
-
end
|
154
|
-
@capture_page = true
|
155
|
-
end
|
156
|
-
true
|
157
|
-
end
|
158
|
-
|
159
|
-
# Read data from a file using exclusive lock
|
160
|
-
#
|
161
|
-
# ==== Parameters
|
162
|
-
# cache_file<String>:: the full path to the file
|
163
|
-
#
|
164
|
-
# ==== Returns
|
165
|
-
# data<String>:: the data that has been read from the file
|
166
|
-
def cache_read_page(cache_file)
|
167
|
-
_data = nil
|
168
|
-
File.open(cache_file, "r") do |cache_data|
|
169
|
-
cache_data.flock(File::LOCK_EX)
|
170
|
-
_data = cache_data.read
|
171
|
-
cache_data.flock(File::LOCK_UN)
|
172
|
-
end
|
173
|
-
_data
|
174
|
-
end
|
175
|
-
|
176
|
-
# Write data to a file using exclusive lock
|
177
|
-
#
|
178
|
-
# ==== Parameters
|
179
|
-
# cache_file<String>:: the full path to the file
|
180
|
-
# data<String>:: the data that will be written to the file
|
181
|
-
def cache_write_page(cache_file, data)
|
182
|
-
File.open(cache_file, "w+") do |cache_data|
|
183
|
-
cache_data.flock(File::LOCK_EX)
|
184
|
-
cache_data.write(data)
|
185
|
-
cache_data.flock(File::LOCK_UN)
|
186
|
-
end
|
187
|
-
true
|
188
|
-
end
|
189
|
-
|
190
|
-
# before filter
|
191
|
-
def cache_page_before
|
192
|
-
# recalls a cached entry or set @capture_page to true in order
|
193
|
-
# to grab the response in the after filter
|
194
|
-
_cache_page
|
195
|
-
end
|
196
|
-
|
197
|
-
# after filter
|
198
|
-
def cache_page_after
|
199
|
-
# takes the body of the response
|
200
|
-
# if the cache entry expired, if it doesn't exist or status is 200
|
201
|
-
_cache_page(body) if @capture_page && status == 200
|
202
|
-
end
|
203
|
-
end
|
@@ -1,88 +0,0 @@
|
|
1
|
-
module Merb::Cache::DatabaseStore::ActiveRecord
|
2
|
-
# Module that provides ActiveRecord support for the database backend
|
3
|
-
|
4
|
-
# The cache model migration
|
5
|
-
class CacheMigration < ActiveRecord::Migration
|
6
|
-
def self.up
|
7
|
-
create_table (Merb::Controller._cache.config[:table_name]), :primary_key => :ckey do |t|
|
8
|
-
t.column :ckey, :string
|
9
|
-
t.column :data, :text
|
10
|
-
t.datetime :expire, :default => nil
|
11
|
-
end
|
12
|
-
end
|
13
|
-
|
14
|
-
def self.down
|
15
|
-
drop_table Merb::Controller._cache.config[:table_name]
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
|
-
# The cache model
|
20
|
-
class CacheModel < ActiveRecord::Base
|
21
|
-
set_table_name Merb::Controller._cache.config[:table_name]
|
22
|
-
|
23
|
-
# Fetch data from the database using the specified key
|
24
|
-
# The entry is deleted if it has expired
|
25
|
-
#
|
26
|
-
# ==== Parameter
|
27
|
-
# key<Sting>:: The key identifying the cache entry
|
28
|
-
#
|
29
|
-
# ==== Returns
|
30
|
-
# data<String, NilClass>::
|
31
|
-
# nil is returned whether the entry expired or was not found
|
32
|
-
def self.cache_get(key)
|
33
|
-
if entry = self.find(:first, :conditions => ["ckey=?", key])
|
34
|
-
return entry.data if entry.expire.nil? || Time.now < entry.expire
|
35
|
-
self.expire(key)
|
36
|
-
end
|
37
|
-
nil
|
38
|
-
end
|
39
|
-
|
40
|
-
# Store data to the database using the specified key
|
41
|
-
#
|
42
|
-
# ==== Parameters
|
43
|
-
# key<Sting>:: The key identifying the cache entry
|
44
|
-
# data<String>:: The data to be put in cache
|
45
|
-
# expire<~minutes>::
|
46
|
-
# The number of minutes (from now) the cache should persist
|
47
|
-
# get<Boolean>::
|
48
|
-
# used internally to behave like this
|
49
|
-
# - when set to true, perform update_or_create on the cache entry
|
50
|
-
# - when set to false, force creation of the cache entry
|
51
|
-
def self.cache_set(key, data, expire = nil, get = true)
|
52
|
-
attributes = {:ckey => key, :data => data, :expire => expire }
|
53
|
-
if get
|
54
|
-
entry = self.find(:first, :conditions => ["ckey=?",key])
|
55
|
-
entry.nil? ? self.create(attributes) : entry.update_attributes(attributes)
|
56
|
-
else
|
57
|
-
self.create(attributes)
|
58
|
-
end
|
59
|
-
true
|
60
|
-
end
|
61
|
-
|
62
|
-
# Expire the cache entry identified by the given key
|
63
|
-
#
|
64
|
-
# ==== Parameter
|
65
|
-
# key<Sting>:: The key identifying the cache entry
|
66
|
-
def self.expire(key)
|
67
|
-
self.delete_all(["ckey=?", key])
|
68
|
-
end
|
69
|
-
|
70
|
-
# Expire the cache entries matching the given key
|
71
|
-
#
|
72
|
-
# ==== Parameter
|
73
|
-
# key<Sting>:: The key matching the cache entries
|
74
|
-
def self.expire_match(key)
|
75
|
-
self.delete_all(["ckey like ?", key + "%"])
|
76
|
-
end
|
77
|
-
|
78
|
-
# Expire all the cache entries
|
79
|
-
def self.expire_all
|
80
|
-
self.delete_all
|
81
|
-
end
|
82
|
-
|
83
|
-
# Perform auto-migration in case the table is unknown in the database
|
84
|
-
def self.check_table
|
85
|
-
CacheMigration.up unless self.table_exists?
|
86
|
-
end
|
87
|
-
end
|
88
|
-
end
|
@@ -1,79 +0,0 @@
|
|
1
|
-
module Merb::Cache::DatabaseStore::DataMapper
|
2
|
-
# Module that provides DataMapper support for the database backend
|
3
|
-
|
4
|
-
# The cache model
|
5
|
-
class CacheModel
|
6
|
-
include DataMapper::Resource
|
7
|
-
storage_names[:default] = Merb::Controller._cache.config[:table_name]
|
8
|
-
property :ckey, String, :length => 255, :lazy => false, :key => true
|
9
|
-
property :data, Text, :lazy => false
|
10
|
-
property :expire, DateTime, :default => nil
|
11
|
-
|
12
|
-
# Fetch data from the database using the specified key
|
13
|
-
# The entry is deleted if it has expired
|
14
|
-
#
|
15
|
-
# ==== Parameter
|
16
|
-
# key<Sting>:: The key identifying the cache entry
|
17
|
-
#
|
18
|
-
# ==== Returns
|
19
|
-
# data<String, NilClass>::
|
20
|
-
# nil is returned whether the entry expired or was not found
|
21
|
-
def self.cache_get(key)
|
22
|
-
if entry = self.get(key)
|
23
|
-
return entry.data if entry.expire.nil? || DateTime.now < entry.expire
|
24
|
-
entry.destroy
|
25
|
-
end
|
26
|
-
nil
|
27
|
-
end
|
28
|
-
|
29
|
-
# Store data to the database using the specified key
|
30
|
-
#
|
31
|
-
# ==== Parameters
|
32
|
-
# key<Sting>:: The key identifying the cache entry
|
33
|
-
# data<String>:: The data to be put in cache
|
34
|
-
# expire<~minutes>::
|
35
|
-
# The number of minutes (from now) the cache should persist
|
36
|
-
# get<Boolean>::
|
37
|
-
# used internally to behave like this:
|
38
|
-
# - when set to true, perform update_or_create on the cache entry
|
39
|
-
# - when set to false, force creation of the cache entry
|
40
|
-
def self.cache_set(key, data, expire = nil, get = true)
|
41
|
-
attributes = {:ckey => key, :data => data,
|
42
|
-
:expire => expire }
|
43
|
-
if get
|
44
|
-
entry = self.get(key)
|
45
|
-
entry.nil? ? self.create(attributes) : entry.update_attributes(attributes)
|
46
|
-
else
|
47
|
-
self.create(attributes)
|
48
|
-
end
|
49
|
-
true
|
50
|
-
end
|
51
|
-
|
52
|
-
# Expire the cache entry identified by the given key
|
53
|
-
#
|
54
|
-
# ==== Parameter
|
55
|
-
# key<Sting>:: The key identifying the cache entry
|
56
|
-
def self.expire(key)
|
57
|
-
entry = self.get(key)
|
58
|
-
entry.destroy unless entry.nil?
|
59
|
-
end
|
60
|
-
|
61
|
-
# Expire the cache entries matching the given key
|
62
|
-
#
|
63
|
-
# ==== Parameter
|
64
|
-
# key<Sting>:: The key matching the cache entries
|
65
|
-
def self.expire_match(key)
|
66
|
-
self.all(:ckey.like => "#{key}%").destroy!
|
67
|
-
end
|
68
|
-
|
69
|
-
# Expire all the cache entries
|
70
|
-
def self.expire_all
|
71
|
-
self.all.destroy!
|
72
|
-
end
|
73
|
-
|
74
|
-
# Perform auto-migration in case the table is unknown in the database
|
75
|
-
def self.check_table
|
76
|
-
self.auto_upgrade!
|
77
|
-
end
|
78
|
-
end
|
79
|
-
end
|
@@ -1,78 +0,0 @@
|
|
1
|
-
module Merb::Cache::DatabaseStore::Sequel
|
2
|
-
# Module that provides Sequel support for the database backend
|
3
|
-
|
4
|
-
# The cache model
|
5
|
-
class CacheModel < Sequel::Model(Merb::Controller._cache.config[:table_name].to_sym)
|
6
|
-
set_schema do
|
7
|
-
primary_key :id
|
8
|
-
varchar :ckey, :index => true
|
9
|
-
varchar :data
|
10
|
-
timestamp :expire, :default => nil
|
11
|
-
end
|
12
|
-
|
13
|
-
# Fetch data from the database using the specified key
|
14
|
-
# The entry is deleted if it has expired
|
15
|
-
#
|
16
|
-
# ==== Parameter
|
17
|
-
# key<Sting>:: The key identifying the cache entry
|
18
|
-
#
|
19
|
-
# ==== Returns
|
20
|
-
# data<String, NilClass>::
|
21
|
-
# nil is returned whether the entry expired or was not found
|
22
|
-
def self.cache_get(key)
|
23
|
-
if entry = self.filter(:ckey => key).single_record(:limit => 1)
|
24
|
-
return entry.data if entry.expire.nil? || Time.now < entry.expire
|
25
|
-
self.expire(key)
|
26
|
-
end
|
27
|
-
nil
|
28
|
-
end
|
29
|
-
|
30
|
-
# Store data to the database using the specified key
|
31
|
-
#
|
32
|
-
# ==== Parameters
|
33
|
-
# key<Sting>:: The key identifying the cache entry
|
34
|
-
# data<String>:: The data to be put in cache
|
35
|
-
# expire<~minutes>::
|
36
|
-
# The number of minutes (from now) the cache should persist
|
37
|
-
# get<Boolean>::
|
38
|
-
# used internally to behave like this
|
39
|
-
# - when set to true, perform update_or_create on the cache entry
|
40
|
-
# - when set to false, force creation of the cache entry
|
41
|
-
def self.cache_set(key, data, expire = nil, get = true)
|
42
|
-
attributes = {:ckey => key, :data => data, :expire => expire }
|
43
|
-
if get
|
44
|
-
entry = self.filter(:ckey => key).single_record(:limit => 1)
|
45
|
-
entry.nil? ? self.create(attributes) : entry.set(attributes)
|
46
|
-
else
|
47
|
-
self.create(attributes)
|
48
|
-
end
|
49
|
-
true
|
50
|
-
end
|
51
|
-
|
52
|
-
# Expire the cache entry identified by the given key
|
53
|
-
#
|
54
|
-
# ==== Parameter
|
55
|
-
# key<Sting>:: The key identifying the cache entry
|
56
|
-
def self.expire(key)
|
57
|
-
self.filter(:ckey => key).delete
|
58
|
-
end
|
59
|
-
|
60
|
-
# Expire the cache entries matching the given key
|
61
|
-
#
|
62
|
-
# ==== Parameter
|
63
|
-
# key<Sting>:: The key matching the cache entries
|
64
|
-
def self.expire_match(key)
|
65
|
-
self.filter{:ckey.like key + "%"}.delete
|
66
|
-
end
|
67
|
-
|
68
|
-
# Expire all the cache entries
|
69
|
-
def self.expire_all
|
70
|
-
self.delete_all
|
71
|
-
end
|
72
|
-
|
73
|
-
# Perform auto-migration in case the table is unknown in the database
|
74
|
-
def self.check_table
|
75
|
-
self.create_table unless self.table_exists?
|
76
|
-
end
|
77
|
-
end
|
78
|
-
end
|
@@ -1,144 +0,0 @@
|
|
1
|
-
class Merb::Cache::DatabaseStore
|
2
|
-
# Provides the database cache store for merb-cache
|
3
|
-
|
4
|
-
def initialize
|
5
|
-
@config = Merb::Controller._cache.config
|
6
|
-
prepare
|
7
|
-
end
|
8
|
-
|
9
|
-
class OrmNotFound < Exception #
|
10
|
-
def initialize
|
11
|
-
super("No valid ORM found (did you specify use_orm in init.rb?)")
|
12
|
-
end
|
13
|
-
end
|
14
|
-
|
15
|
-
# Requires the ORM at startup, raising an OrmNotFound exception if
|
16
|
-
# the backend is not found
|
17
|
-
Merb::Controller._cache.config[:table_name] ||= "merb_cache"
|
18
|
-
if defined?(Merb::Orms::ActiveRecord)
|
19
|
-
require "merb-cache/cache-store/database-activerecord.rb"
|
20
|
-
include Merb::Cache::DatabaseStore::ActiveRecord
|
21
|
-
elsif defined?(Merb::Orms::DataMapper)
|
22
|
-
require "merb-cache/cache-store/database-datamapper.rb"
|
23
|
-
include Merb::Cache::DatabaseStore::DataMapper
|
24
|
-
elsif defined?(Merb::Orms::Sequel)
|
25
|
-
require "merb-cache/cache-store/database-sequel.rb"
|
26
|
-
include Merb::Cache::DatabaseStore::Sequel
|
27
|
-
else
|
28
|
-
raise OrmNotFound
|
29
|
-
end
|
30
|
-
|
31
|
-
# This method is there to ensure minimal requirements are met
|
32
|
-
# (file permissions, table exists, connected to server, ...)
|
33
|
-
def prepare
|
34
|
-
CacheModel.check_table
|
35
|
-
true
|
36
|
-
end
|
37
|
-
|
38
|
-
# Checks whether a cache entry exists
|
39
|
-
#
|
40
|
-
# ==== Parameter
|
41
|
-
# key<String>:: The key identifying the cache entry
|
42
|
-
#
|
43
|
-
# ==== Returns
|
44
|
-
# true if the cache entry exists, false otherwise
|
45
|
-
def cached?(key)
|
46
|
-
not CacheModel.cache_get(key).nil?
|
47
|
-
end
|
48
|
-
|
49
|
-
# Capture or restore the data in cache.
|
50
|
-
# If the cache entry expired or does not exist, the data are taken
|
51
|
-
# from the execution of the block, marshalled and stored in cache.
|
52
|
-
# Otherwise, the data are loaded from the cache and returned unmarshalled
|
53
|
-
#
|
54
|
-
# ==== Parameters
|
55
|
-
# _controller<Merb::Controller>:: The instance of the current controller
|
56
|
-
# key<String>:: The key identifying the cache entry
|
57
|
-
# from_now<~minutes>::
|
58
|
-
# The number of minutes (from now) the cache should persist
|
59
|
-
# &block:: The template to be used or not
|
60
|
-
#
|
61
|
-
# ==== Additional information
|
62
|
-
# When fetching data (the cache entry exists and has not expired)
|
63
|
-
# The data are loaded from the cache and returned unmarshalled.
|
64
|
-
# Otherwise:
|
65
|
-
# The controller is used to capture the rendered template (from the block).
|
66
|
-
# It uses the capture_#{engine} and concat_#{engine} methods to do so.
|
67
|
-
# The captured data are then marshalled and stored.
|
68
|
-
def cache(_controller, key, from_now = nil, &block)
|
69
|
-
_data = CacheModel.cache_get(key)
|
70
|
-
if _data.nil?
|
71
|
-
_expire = from_now ? from_now.minutes.from_now : nil
|
72
|
-
_data = _controller.send(:capture, &block)
|
73
|
-
CacheModel.cache_set(key, Marshal.dump(_data), _expire, false)
|
74
|
-
else
|
75
|
-
_data = Marshal.load(_data)
|
76
|
-
end
|
77
|
-
_controller.send(:concat, _data, block.binding)
|
78
|
-
true
|
79
|
-
end
|
80
|
-
|
81
|
-
# Store data to the database using the specified key
|
82
|
-
#
|
83
|
-
# ==== Parameters
|
84
|
-
# key<Sting>:: The key identifying the cache entry
|
85
|
-
# data<String>:: The data to be put in cache
|
86
|
-
# from_now<~minutes>::
|
87
|
-
# The number of minutes (from now) the cache should persist
|
88
|
-
def cache_set(key, data, from_now = nil)
|
89
|
-
_expire = from_now ? from_now.minutes.from_now : nil
|
90
|
-
CacheModel.cache_set(key, Marshal.dump(data), _expire)
|
91
|
-
Merb.logger.info("cache: set (#{key})")
|
92
|
-
true
|
93
|
-
end
|
94
|
-
|
95
|
-
# Fetch data from the database using the specified key
|
96
|
-
# The entry is deleted if it has expired
|
97
|
-
#
|
98
|
-
# ==== Parameter
|
99
|
-
# key<Sting>:: The key identifying the cache entry
|
100
|
-
#
|
101
|
-
# ==== Returns
|
102
|
-
# data<String, NilClass>::
|
103
|
-
# nil is returned whether the entry expired or was not found
|
104
|
-
def cache_get(key)
|
105
|
-
data = CacheModel.cache_get(key)
|
106
|
-
Merb.logger.info("cache: #{data.nil? ? "miss" : "hit"} (#{key})")
|
107
|
-
data.nil? ? nil : Marshal.load(data)
|
108
|
-
end
|
109
|
-
|
110
|
-
# Expire the cache entry identified by the given key
|
111
|
-
#
|
112
|
-
# ==== Parameter
|
113
|
-
# key<Sting>:: The key identifying the cache entry
|
114
|
-
def expire(key)
|
115
|
-
CacheModel.expire(key)
|
116
|
-
Merb.logger.info("cache: expired (#{key})")
|
117
|
-
true
|
118
|
-
end
|
119
|
-
|
120
|
-
# Expire the cache entries matching the given key
|
121
|
-
#
|
122
|
-
# ==== Parameter
|
123
|
-
# key<Sting>:: The key matching the cache entries
|
124
|
-
def expire_match(key)
|
125
|
-
CacheModel.expire_match(key)
|
126
|
-
Merb.logger.info("cache: expired matching (#{key})")
|
127
|
-
true
|
128
|
-
end
|
129
|
-
|
130
|
-
# Expire all the cache entries
|
131
|
-
def expire_all
|
132
|
-
CacheModel.expire_all
|
133
|
-
Merb.logger.info("cache: expired all")
|
134
|
-
true
|
135
|
-
end
|
136
|
-
|
137
|
-
# Gives info on the current cache store
|
138
|
-
#
|
139
|
-
# ==== Returns
|
140
|
-
# The type of the current cache store
|
141
|
-
def cache_store_type
|
142
|
-
"database"
|
143
|
-
end
|
144
|
-
end
|
@@ -1,106 +0,0 @@
|
|
1
|
-
class Merb::Cache::DummyStore
|
2
|
-
# Provides dummy cache store for merb-cache
|
3
|
-
|
4
|
-
def initialize
|
5
|
-
@config = Merb::Controller._cache.config
|
6
|
-
prepare
|
7
|
-
end
|
8
|
-
|
9
|
-
# This method is there to ensure minimal requirements are met
|
10
|
-
# (directories are accessible, table exists, connected to server, ...)
|
11
|
-
def prepare
|
12
|
-
true
|
13
|
-
end
|
14
|
-
|
15
|
-
# Checks whether a cache entry exists
|
16
|
-
#
|
17
|
-
# ==== Parameter
|
18
|
-
# key<String>:: The key identifying the cache entry
|
19
|
-
#
|
20
|
-
# ==== Returns
|
21
|
-
# true if the cache entry exists, false otherwise
|
22
|
-
def cached?(key)
|
23
|
-
false
|
24
|
-
end
|
25
|
-
|
26
|
-
# Capture or restore the data in cache.
|
27
|
-
# If the cache entry expired or does not exist, the data are taken
|
28
|
-
# from the execution of the block, marshalled and stored in cache.
|
29
|
-
# Otherwise, the data are loaded from the cache and returned unmarshalled
|
30
|
-
#
|
31
|
-
# ==== Parameters
|
32
|
-
# _controller<Merb::Controller>:: The instance of the current controller
|
33
|
-
# key<String>:: The key identifying the cache entry
|
34
|
-
# from_now<~minutes>::
|
35
|
-
# The number of minutes (from now) the cache should persist
|
36
|
-
# &block:: The template to be used or not
|
37
|
-
#
|
38
|
-
# ==== Additional information
|
39
|
-
# When fetching data (the cache entry exists and has not expired)
|
40
|
-
# The data are loaded from the cache and returned unmarshalled.
|
41
|
-
# Otherwise:
|
42
|
-
# The controller is used to capture the rendered template (from the block).
|
43
|
-
# It uses the capture_#{engine} and concat_#{engine} methods to do so.
|
44
|
-
# The captured data are then marshalled and stored.
|
45
|
-
def cache(_controller, key, from_now = nil, &block)
|
46
|
-
_data = _controller.send(:capture, &block)
|
47
|
-
_controller.send(:concat, _data, block.binding)
|
48
|
-
true
|
49
|
-
end
|
50
|
-
|
51
|
-
# Store data to memcache using the specified key
|
52
|
-
#
|
53
|
-
# ==== Parameters
|
54
|
-
# key<Sting>:: The key identifying the cache entry
|
55
|
-
# data<String>:: The data to be put in cache
|
56
|
-
# from_now<~minutes>::
|
57
|
-
# The number of minutes (from now) the cache should persist
|
58
|
-
def cache_set(key, data, from_now = nil)
|
59
|
-
true
|
60
|
-
end
|
61
|
-
|
62
|
-
# Fetch data from memcache using the specified key
|
63
|
-
# The entry is deleted if it has expired
|
64
|
-
#
|
65
|
-
# ==== Parameter
|
66
|
-
# key<Sting>:: The key identifying the cache entry
|
67
|
-
#
|
68
|
-
# ==== Returns
|
69
|
-
# data<String, NilClass>::
|
70
|
-
# nil is returned whether the entry expired or was not found
|
71
|
-
def cache_get(key)
|
72
|
-
nil
|
73
|
-
end
|
74
|
-
|
75
|
-
# Expire the cache entry identified by the given key
|
76
|
-
#
|
77
|
-
# ==== Parameter
|
78
|
-
# key<Sting>:: The key identifying the cache entry
|
79
|
-
def expire(key)
|
80
|
-
true
|
81
|
-
end
|
82
|
-
|
83
|
-
# Expire the cache entries matching the given key
|
84
|
-
#
|
85
|
-
# ==== Parameter
|
86
|
-
# key<Sting>:: The key matching the cache entries
|
87
|
-
#
|
88
|
-
# ==== Warning !
|
89
|
-
# This does not work in memcache.
|
90
|
-
def expire_match(key)
|
91
|
-
true
|
92
|
-
end
|
93
|
-
|
94
|
-
# Expire all the cache entries
|
95
|
-
def expire_all
|
96
|
-
true
|
97
|
-
end
|
98
|
-
|
99
|
-
# Gives info on the current cache store
|
100
|
-
#
|
101
|
-
# ==== Returns
|
102
|
-
# The type of the current cache store
|
103
|
-
def cache_store_type
|
104
|
-
"dummy"
|
105
|
-
end
|
106
|
-
end
|