merb-cache 0.9.2
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +20 -0
- data/README +160 -0
- data/Rakefile +77 -0
- data/TODO +2 -0
- data/lib/merb-cache/cache-action.rb +132 -0
- data/lib/merb-cache/cache-fragment.rb +95 -0
- data/lib/merb-cache/cache-page.rb +184 -0
- data/lib/merb-cache/cache-store/database-activerecord.rb +88 -0
- data/lib/merb-cache/cache-store/database-datamapper.rb +79 -0
- data/lib/merb-cache/cache-store/database-sequel.rb +78 -0
- data/lib/merb-cache/cache-store/database.rb +144 -0
- data/lib/merb-cache/cache-store/dummy.rb +106 -0
- data/lib/merb-cache/cache-store/file.rb +192 -0
- data/lib/merb-cache/cache-store/memcache.rb +195 -0
- data/lib/merb-cache/cache-store/memory.rb +168 -0
- data/lib/merb-cache/merb-cache.rb +164 -0
- data/lib/merb-cache/merbtasks.rb +6 -0
- data/lib/merb-cache.rb +10 -0
- metadata +82 -0
@@ -0,0 +1,195 @@
|
|
1
|
+
class Merb::Cache::MemcacheStore
|
2
|
+
# Provides the memcache cache store for merb-cache
|
3
|
+
|
4
|
+
def initialize
|
5
|
+
@config = Merb::Controller._cache.config
|
6
|
+
prepare
|
7
|
+
end
|
8
|
+
|
9
|
+
class NotReady < Exception #:nodoc:
|
10
|
+
def initialize
|
11
|
+
super("Memcache server is not ready")
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
class NotDefined < Exception #:nodoc:
|
16
|
+
def initialize
|
17
|
+
super("Memcache is not defined (require it in init.rb)")
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
# This method is there to ensure minimal requirements are met
|
22
|
+
# (directories are accessible, table exists, connected to server, ...)
|
23
|
+
def prepare
|
24
|
+
namespace = @config[:namespace] || 'merb-cache'
|
25
|
+
host = @config[:host] || '127.0.0.1:11211'
|
26
|
+
@memcache = MemCache.new(host, {:namespace => namespace})
|
27
|
+
@tracking_key = "_#{namespace}_keys" unless @config[:no_tracking]
|
28
|
+
raise NotReady unless @memcache.active?
|
29
|
+
true
|
30
|
+
rescue NameError
|
31
|
+
raise NotDefined
|
32
|
+
end
|
33
|
+
|
34
|
+
# Checks whether a cache entry exists
|
35
|
+
#
|
36
|
+
# ==== Parameter
|
37
|
+
# key<String>:: The key identifying the cache entry
|
38
|
+
#
|
39
|
+
# ==== Returns
|
40
|
+
# true if the cache entry exists, false otherwise
|
41
|
+
def cached?(key)
|
42
|
+
not @memcache.get(key).nil?
|
43
|
+
end
|
44
|
+
|
45
|
+
# Capture or restore the data in cache.
|
46
|
+
# If the cache entry expired or does not exist, the data are taken
|
47
|
+
# from the execution of the block, marshalled and stored in cache.
|
48
|
+
# Otherwise, the data are loaded from the cache and returned unmarshalled
|
49
|
+
#
|
50
|
+
# ==== Parameters
|
51
|
+
# _controller<Merb::Controller>:: The instance of the current controller
|
52
|
+
# key<String>:: The key identifying the cache entry
|
53
|
+
# from_now<~minutes>::
|
54
|
+
# The number of minutes (from now) the cache should persist
|
55
|
+
# &block:: The template to be used or not
|
56
|
+
#
|
57
|
+
# ==== Additional information
|
58
|
+
# When fetching data (the cache entry exists and has not expired)
|
59
|
+
# The data are loaded from the cache and returned unmarshalled.
|
60
|
+
# Otherwise:
|
61
|
+
# The controller is used to capture the rendered template (from the block).
|
62
|
+
# It uses the capture_#{engine} and concat_#{engine} methods to do so.
|
63
|
+
# The captured data are then marshalled and stored.
|
64
|
+
def cache(_controller, key, from_now = nil, &block)
|
65
|
+
_data = @memcache.get(key)
|
66
|
+
if _data.nil?
|
67
|
+
_expire = from_now ? from_now.minutes.from_now.to_i : 0
|
68
|
+
_data = _controller.send(:capture, &block)
|
69
|
+
@memcache.set(key, _data, _expire)
|
70
|
+
end
|
71
|
+
_controller.send(:concat, _data, block.binding)
|
72
|
+
true
|
73
|
+
end
|
74
|
+
|
75
|
+
# Store data to memcache using the specified key
|
76
|
+
#
|
77
|
+
# ==== Parameters
|
78
|
+
# key<Sting>:: The key identifying the cache entry
|
79
|
+
# data<String>:: The data to be put in cache
|
80
|
+
# from_now<~minutes>::
|
81
|
+
# The number of minutes (from now) the cache should persist
|
82
|
+
def cache_set(key, data, from_now = nil)
|
83
|
+
_expire = from_now ? from_now.minutes.from_now.to_i : 0
|
84
|
+
@memcache.set(key, data, _expire)
|
85
|
+
cache_start_tracking(key)
|
86
|
+
Merb.logger.info("cache: set (#{key})")
|
87
|
+
true
|
88
|
+
end
|
89
|
+
|
90
|
+
# Fetch data from memcache using the specified key
|
91
|
+
# The entry is deleted if it has expired
|
92
|
+
#
|
93
|
+
# ==== Parameter
|
94
|
+
# key<Sting>:: The key identifying the cache entry
|
95
|
+
#
|
96
|
+
# ==== Returns
|
97
|
+
# data<String, NilClass>::
|
98
|
+
# nil is returned whether the entry expired or was not found
|
99
|
+
def cache_get(key)
|
100
|
+
data = @memcache.get(key)
|
101
|
+
Merb.logger.info("cache: #{data.nil? ? "miss" : "hit"} (#{key})")
|
102
|
+
data
|
103
|
+
end
|
104
|
+
|
105
|
+
# Expire the cache entry identified by the given key
|
106
|
+
#
|
107
|
+
# ==== Parameter
|
108
|
+
# key<Sting>:: The key identifying the cache entry
|
109
|
+
def expire(key)
|
110
|
+
@memcache.delete(key)
|
111
|
+
cache_stop_tracking(key)
|
112
|
+
Merb.logger.info("cache: expired (#{key})")
|
113
|
+
true
|
114
|
+
end
|
115
|
+
|
116
|
+
# Expire the cache entries matching the given key
|
117
|
+
#
|
118
|
+
# ==== Parameter
|
119
|
+
# key<Sting>:: The key matching the cache entries
|
120
|
+
#
|
121
|
+
# ==== Additional info
|
122
|
+
# In memcache this requires to keep track of all keys (on by default).
|
123
|
+
# If you don't need this, set :no_tracking => true in the config.
|
124
|
+
def expire_match(key)
|
125
|
+
if @tracking_key
|
126
|
+
for _key in get_tracked_keys
|
127
|
+
expire(_key) if /#{key}/ =~ _key
|
128
|
+
end
|
129
|
+
else
|
130
|
+
Merb.logger.info("cache: expire_match is not supported with memcache (set :no_tracking => false in your config")
|
131
|
+
end
|
132
|
+
true
|
133
|
+
end
|
134
|
+
|
135
|
+
# Expire all the cache entries
|
136
|
+
def expire_all
|
137
|
+
@memcache.flush_all
|
138
|
+
stop_tracking_keys
|
139
|
+
Merb.logger.info("cache: expired all")
|
140
|
+
true
|
141
|
+
end
|
142
|
+
|
143
|
+
# Gives info on the current cache store
|
144
|
+
#
|
145
|
+
# ==== Returns
|
146
|
+
# The type of the current cache store
|
147
|
+
def cache_store_type
|
148
|
+
"memcache"
|
149
|
+
end
|
150
|
+
|
151
|
+
private
|
152
|
+
|
153
|
+
# Store the tracked keys in memcache (used by expire_match)
|
154
|
+
#
|
155
|
+
# ==== Parameter
|
156
|
+
# keys<Array[String]>:: The keys to keep track of
|
157
|
+
def set_tracked_keys(keys)
|
158
|
+
@memcache.set(@tracking_key, keys)
|
159
|
+
end
|
160
|
+
|
161
|
+
# Retrieve tracked keys from memcache
|
162
|
+
#
|
163
|
+
# ==== Returns
|
164
|
+
# keys<Array[String]>:: The tracked keys
|
165
|
+
def get_tracked_keys
|
166
|
+
@memcache.get(@tracking_key) || []
|
167
|
+
end
|
168
|
+
|
169
|
+
# Remove all tracked keys
|
170
|
+
def stop_tracking_keys
|
171
|
+
@memcache.delete(@tracking_key) if @tracking_key
|
172
|
+
end
|
173
|
+
|
174
|
+
# Add a key in the array of tracked keys (used by expire_match)
|
175
|
+
#
|
176
|
+
# ==== Parameter
|
177
|
+
# key<String>:: the key to add
|
178
|
+
def cache_start_tracking(key)
|
179
|
+
return unless @tracking_key
|
180
|
+
keys = get_tracked_keys
|
181
|
+
keys.push(key)
|
182
|
+
set_tracked_keys(keys)
|
183
|
+
end
|
184
|
+
|
185
|
+
# Remove a key from the array of tracked keys (used by expire_match)
|
186
|
+
#
|
187
|
+
# ==== Parameter
|
188
|
+
# key<String>:: the key to remove
|
189
|
+
def cache_stop_tracking(key)
|
190
|
+
return unless @tracking_key
|
191
|
+
keys = get_tracked_keys
|
192
|
+
keys.delete(key)
|
193
|
+
set_tracked_keys(keys)
|
194
|
+
end
|
195
|
+
end
|
@@ -0,0 +1,168 @@
|
|
1
|
+
class Merb::Cache::MemoryStore
|
2
|
+
# Provides the memory cache store for merb-cache
|
3
|
+
|
4
|
+
def initialize
|
5
|
+
@config = Merb::Controller._cache.config
|
6
|
+
@cache = {}
|
7
|
+
@mutex = Mutex.new
|
8
|
+
prepare
|
9
|
+
end
|
10
|
+
|
11
|
+
# This method is there to ensure minimal requirements are met
|
12
|
+
# (directories are accessible, table exists, connected to server, ...)
|
13
|
+
def prepare
|
14
|
+
true
|
15
|
+
end
|
16
|
+
|
17
|
+
# Checks whether a cache entry exists
|
18
|
+
#
|
19
|
+
# ==== Parameter
|
20
|
+
# key<String>:: The key identifying the cache entry
|
21
|
+
#
|
22
|
+
# ==== Returns
|
23
|
+
# true if the cache entry exists, false otherwise
|
24
|
+
def cached?(key)
|
25
|
+
if @cache.key?(key)
|
26
|
+
_data, _expire = *cache_read(key)
|
27
|
+
return true if _expire.nil? || Time.now < _expire
|
28
|
+
expire(key)
|
29
|
+
end
|
30
|
+
false
|
31
|
+
end
|
32
|
+
|
33
|
+
# Capture or restore the data in cache.
|
34
|
+
# If the cache entry expired or does not exist, the data are taken
|
35
|
+
# from the execution of the block, marshalled and stored in cache.
|
36
|
+
# Otherwise, the data are loaded from the cache and returned unmarshalled
|
37
|
+
#
|
38
|
+
# ==== Parameters
|
39
|
+
# _controller<Merb::Controller>:: The instance of the current controller
|
40
|
+
# key<String>:: The key identifying the cache entry
|
41
|
+
# from_now<~minutes>::
|
42
|
+
# The number of minutes (from now) the cache should persist
|
43
|
+
# &block:: The template to be used or not
|
44
|
+
#
|
45
|
+
# ==== Additional information
|
46
|
+
# When fetching data (the cache entry exists and has not expired)
|
47
|
+
# The data are loaded from the cache and returned unmarshalled.
|
48
|
+
# Otherwise:
|
49
|
+
# The controller is used to capture the rendered template (from the block).
|
50
|
+
# It uses the capture_#{engine} and concat_#{engine} methods to do so.
|
51
|
+
# The captured data are then marshalled and stored.
|
52
|
+
def cache(_controller, key, from_now = nil, &block)
|
53
|
+
if @cache.key?(key)
|
54
|
+
_data, _expire = *cache_read(key)
|
55
|
+
_cache_hit = _expire.nil? || Time.now < _expire
|
56
|
+
end
|
57
|
+
unless _cache_hit
|
58
|
+
_expire = from_now ? from_now.minutes.from_now : nil
|
59
|
+
_data = _controller.send(:capture, &block)
|
60
|
+
cache_write(key, [_data, _expire])
|
61
|
+
end
|
62
|
+
_controller.send(:concat, _data, block.binding)
|
63
|
+
true
|
64
|
+
end
|
65
|
+
|
66
|
+
# Store data to the file using the specified key
|
67
|
+
#
|
68
|
+
# ==== Parameters
|
69
|
+
# key<Sting>:: The key identifying the cache entry
|
70
|
+
# data<String>:: The data to be put in cache
|
71
|
+
# from_now<~minutes>::
|
72
|
+
# The number of minutes (from now) the cache should persist
|
73
|
+
def cache_set(key, data, from_now = nil)
|
74
|
+
_expire = from_now ? from_now.minutes.from_now : nil
|
75
|
+
cache_write(key, [data, _expire])
|
76
|
+
Merb.logger.info("cache: set (#{key})")
|
77
|
+
true
|
78
|
+
end
|
79
|
+
|
80
|
+
# Fetch data from the file using the specified key
|
81
|
+
# The entry is deleted if it has expired
|
82
|
+
#
|
83
|
+
# ==== Parameter
|
84
|
+
# key<Sting>:: The key identifying the cache entry
|
85
|
+
#
|
86
|
+
# ==== Returns
|
87
|
+
# data<String, NilClass>::
|
88
|
+
# nil is returned whether the entry expired or was not found
|
89
|
+
def cache_get(key)
|
90
|
+
if @cache.key?(key)
|
91
|
+
_data, _expire = *cache_read(key)
|
92
|
+
if _expire.nil? || Time.now < _expire
|
93
|
+
Merb.logger.info("cache: hit (#{key})")
|
94
|
+
return _data
|
95
|
+
end
|
96
|
+
@mutex.synchronize do @cache.delete(key) end
|
97
|
+
end
|
98
|
+
Merb.logger.info("cache: miss (#{key})")
|
99
|
+
nil
|
100
|
+
end
|
101
|
+
|
102
|
+
# Expire the cache entry identified by the given key
|
103
|
+
#
|
104
|
+
# ==== Parameter
|
105
|
+
# key<Sting>:: The key identifying the cache entry
|
106
|
+
def expire(key)
|
107
|
+
@mutex.synchronize do
|
108
|
+
@cache.delete(key)
|
109
|
+
end
|
110
|
+
Merb.logger.info("cache: expired (#{key})")
|
111
|
+
true
|
112
|
+
end
|
113
|
+
|
114
|
+
# Expire the cache entries matching the given key
|
115
|
+
#
|
116
|
+
# ==== Parameter
|
117
|
+
# key<Sting>:: The key matching the cache entries
|
118
|
+
def expire_match(key)
|
119
|
+
@mutex.synchronize do
|
120
|
+
@cache.delete_if do |k,v| k.match(/#{key}/) end
|
121
|
+
end
|
122
|
+
Merb.logger.info("cache: expired matching (#{key})")
|
123
|
+
true
|
124
|
+
end
|
125
|
+
|
126
|
+
# Expire all the cache entries
|
127
|
+
def expire_all
|
128
|
+
@mutex.synchronize do
|
129
|
+
@cache.clear
|
130
|
+
end
|
131
|
+
Merb.logger.info("cache: expired all")
|
132
|
+
true
|
133
|
+
end
|
134
|
+
|
135
|
+
# Gives info on the current cache store
|
136
|
+
#
|
137
|
+
# ==== Returns
|
138
|
+
# The type of the current cache store
|
139
|
+
def cache_store_type
|
140
|
+
"memory"
|
141
|
+
end
|
142
|
+
|
143
|
+
private
|
144
|
+
|
145
|
+
# Read data from the memory hash table using mutex
|
146
|
+
#
|
147
|
+
# ==== Parameters
|
148
|
+
# cache_file<String>:: The key identifying the cache entry
|
149
|
+
#
|
150
|
+
# ==== Returns
|
151
|
+
# _data<String>:: The data fetched from the cache
|
152
|
+
def cache_read(key)
|
153
|
+
@mutex.synchronize do
|
154
|
+
@cache[key]
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
# Write data to the memory hash table using mutex
|
159
|
+
#
|
160
|
+
# ==== Parameters
|
161
|
+
# cache_file<String>:: The key identifying the cache entry
|
162
|
+
# data<String>:: The data to be put in cache
|
163
|
+
def cache_write(key, data)
|
164
|
+
@mutex.synchronize do
|
165
|
+
@cache[key] = data
|
166
|
+
end
|
167
|
+
end
|
168
|
+
end
|
@@ -0,0 +1,164 @@
|
|
1
|
+
require "merb-cache/cache-action"
|
2
|
+
require "merb-cache/cache-page"
|
3
|
+
require "merb-cache/cache-fragment"
|
4
|
+
|
5
|
+
class Merb::Cache
|
6
|
+
attr_reader :config, :store
|
7
|
+
|
8
|
+
class StoreNotFound < Exception #:nodoc:
|
9
|
+
def initialize(cache_store)
|
10
|
+
super("cache_store (#{cache_store}) not found (not implemented?)")
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
DEFAULT_CONFIG = {
|
15
|
+
:cache_html_directory => Merb.dir_for(:public) / "cache",
|
16
|
+
|
17
|
+
#:store => "database",
|
18
|
+
#:table_name => "merb_cache",
|
19
|
+
|
20
|
+
#:disable => "development", # disable merb-cache in development
|
21
|
+
#:disable => true, # disable merb-cache in all environments
|
22
|
+
|
23
|
+
:store => "file",
|
24
|
+
:cache_directory => Merb.root_path("tmp/cache"),
|
25
|
+
|
26
|
+
#:store => "memcache",
|
27
|
+
#:host => "127.0.0.1:11211",
|
28
|
+
#:namespace => "merb_cache",
|
29
|
+
#:track_keys => true,
|
30
|
+
|
31
|
+
#:store => "memory",
|
32
|
+
# store could be: file, memcache, memory, database, dummy, ...
|
33
|
+
}
|
34
|
+
|
35
|
+
# Called in the after_app_loads loop and instantiate the right backend
|
36
|
+
#
|
37
|
+
# ==== Raises
|
38
|
+
# Store#NotFound::
|
39
|
+
# If the cache_store mentionned in the config is unknown
|
40
|
+
def start
|
41
|
+
@config = DEFAULT_CONFIG.merge(Merb::Plugins.config[:merb_cache] || {})
|
42
|
+
if @config[:disable] == true || Merb.environment == @config[:disable]
|
43
|
+
config[:store] = "dummy"
|
44
|
+
end
|
45
|
+
@config[:cache_html_directory] ||= Merb.dir_for(:public) / "cache"
|
46
|
+
require "merb-cache/cache-store/#{@config[:store]}"
|
47
|
+
@store = Merb::Cache.const_get("#{@config[:store].capitalize}Store").new
|
48
|
+
Merb.logger.info("Using #{@config[:store]} cache")
|
49
|
+
rescue LoadError
|
50
|
+
raise Merb::Cache::StoreNotFound, @config[:store].inspect
|
51
|
+
end
|
52
|
+
|
53
|
+
# Compute a cache key and yield it to the given block
|
54
|
+
# It is used by the #expire_page, #expire_action and #expire methods.
|
55
|
+
#
|
56
|
+
# ==== Parameters
|
57
|
+
# options<String, Hash>:: The key or the Hash that will be used to build the key
|
58
|
+
# controller<String>:: The name of the controller
|
59
|
+
# controller_based<Boolean>:: only used by action and page caching
|
60
|
+
#
|
61
|
+
# ==== Options (options)
|
62
|
+
# :key<String>:: The complete or partial key that will be computed.
|
63
|
+
# :action<String>:: The action name that will be used to compute the key
|
64
|
+
# :controller<String>:: The controller name that will be part of the key
|
65
|
+
# :params<Array[String]>::
|
66
|
+
# The params will be joined together (with '/') and added to the key
|
67
|
+
# :match<Boolean, String>::
|
68
|
+
# true, it will try to match multiple cache entries
|
69
|
+
# string, shortcut for {:key => "mykey", :match => true}
|
70
|
+
#
|
71
|
+
# ==== Examples
|
72
|
+
# expire(:key => "root_key", :params => [session[:me], params[:id]])
|
73
|
+
# expire(:match => "root_key")
|
74
|
+
# expire_action(:action => 'list')
|
75
|
+
# expire_page(:action => 'show', :controller => 'news')
|
76
|
+
#
|
77
|
+
# ==== Returns
|
78
|
+
# The result of the given block
|
79
|
+
#
|
80
|
+
def expire_key_for(options, controller, controller_based = false)
|
81
|
+
key = ""
|
82
|
+
if options.is_a? Hash
|
83
|
+
case
|
84
|
+
when key = options[:key]
|
85
|
+
when action = options[:action]
|
86
|
+
controller = options[:controller] || controller
|
87
|
+
key = "/#{controller}/#{action}"
|
88
|
+
when match = options[:match]
|
89
|
+
key = match
|
90
|
+
end
|
91
|
+
if _params = options[:params]
|
92
|
+
key += "/" + _params.join("/")
|
93
|
+
end
|
94
|
+
yield key, !options[:match].nil?
|
95
|
+
else
|
96
|
+
yield controller_based ? "/#{controller}/#{options}" : options, false
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
# Compute a cache key based on the given parameters
|
101
|
+
# Only used by the #cached_page?, #cached_action?, #cached?, #cache,
|
102
|
+
# #cache_get and #cache_set methods
|
103
|
+
#
|
104
|
+
# ==== Parameters
|
105
|
+
# options<String, Hash>:: The key or the Hash that will be used to build the key
|
106
|
+
# controller<String>:: The name of the controller
|
107
|
+
# controller_based<Boolean>:: only used by action and page caching
|
108
|
+
#
|
109
|
+
# ==== Options (options)
|
110
|
+
# :key<String>:: The complete or partial key that will be computed.
|
111
|
+
# :action<String>:: The action name that will be used to compute the key
|
112
|
+
# :controller<String>:: The controller name that will be part of the key
|
113
|
+
# :params<Array[String]>::
|
114
|
+
# The params will be joined together (with '/') and added to the key
|
115
|
+
#
|
116
|
+
# ==== Examples
|
117
|
+
# cache_set("my_key", @data)
|
118
|
+
# cache_get(:key => "root_key", :params => [session[:me], params[:id]])
|
119
|
+
#
|
120
|
+
# ==== Returns
|
121
|
+
# The computed key
|
122
|
+
def key_for(options, controller, controller_based = false)
|
123
|
+
key = ""
|
124
|
+
if options.is_a? Hash
|
125
|
+
case
|
126
|
+
when key = options[:key]
|
127
|
+
when action = options[:action]
|
128
|
+
controller = options[:controller] || controller
|
129
|
+
key = "/#{controller}/#{action}"
|
130
|
+
end
|
131
|
+
if _params = options[:params]
|
132
|
+
key += "/" + _params.join("/")
|
133
|
+
end
|
134
|
+
else
|
135
|
+
key = controller_based ? "/#{controller}/#{options}" : options
|
136
|
+
end
|
137
|
+
key
|
138
|
+
end
|
139
|
+
|
140
|
+
module ControllerInstanceMethods
|
141
|
+
# Mixed in Merb::Controller and provides expire_all for action and fragment caching.
|
142
|
+
def expire_all
|
143
|
+
Merb::Controller._cache.store.expire_all
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
module Merb #:nodoc:
|
149
|
+
class Controller #:nodoc:
|
150
|
+
cattr_reader :_cache
|
151
|
+
@@_cache = Merb::Cache.new
|
152
|
+
# extends Merb::Controller with new instance methods
|
153
|
+
include Merb::Cache::ControllerInstanceMethods
|
154
|
+
class << self #:nodoc:
|
155
|
+
# extends Merb::Controller with new class methods
|
156
|
+
include Merb::Cache::ControllerClassMethods
|
157
|
+
end
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
Merb::BootLoader.after_app_loads do
|
162
|
+
# the cache starts after the application is loaded
|
163
|
+
Merb::Controller._cache.start
|
164
|
+
end
|
data/lib/merb-cache.rb
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
if defined?(Merb::Plugins)
|
2
|
+
Merb::Plugins.add_rakefiles "merb-cache/merbtasks"
|
3
|
+
unless 1.respond_to? :minutes
|
4
|
+
class Numeric #:nodoc:
|
5
|
+
def minutes; self * 60; end
|
6
|
+
def from_now(now = Time.now); now + self; end
|
7
|
+
end
|
8
|
+
end
|
9
|
+
require "merb-cache/merb-cache"
|
10
|
+
end
|
metadata
ADDED
@@ -0,0 +1,82 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: merb-cache
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.9.2
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Alex Boussinet
|
8
|
+
autorequire: merb-cache
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2008-03-24 00:00:00 -05:00
|
13
|
+
default_executable:
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: merb-core
|
17
|
+
version_requirement:
|
18
|
+
version_requirements: !ruby/object:Gem::Requirement
|
19
|
+
requirements:
|
20
|
+
- - ">="
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: 0.9.2
|
23
|
+
version:
|
24
|
+
description: Merb plugin that provides caching (page, action, fragment, object)
|
25
|
+
email: alex.boussinet@gmail.com
|
26
|
+
executables: []
|
27
|
+
|
28
|
+
extensions: []
|
29
|
+
|
30
|
+
extra_rdoc_files:
|
31
|
+
- README
|
32
|
+
- LICENSE
|
33
|
+
- TODO
|
34
|
+
files:
|
35
|
+
- LICENSE
|
36
|
+
- README
|
37
|
+
- Rakefile
|
38
|
+
- TODO
|
39
|
+
- lib/merb-cache
|
40
|
+
- lib/merb-cache/cache-action.rb
|
41
|
+
- lib/merb-cache/cache-fragment.rb
|
42
|
+
- lib/merb-cache/cache-page.rb
|
43
|
+
- lib/merb-cache/cache-store
|
44
|
+
- lib/merb-cache/cache-store/database-activerecord.rb
|
45
|
+
- lib/merb-cache/cache-store/database-datamapper.rb
|
46
|
+
- lib/merb-cache/cache-store/database-sequel.rb
|
47
|
+
- lib/merb-cache/cache-store/database.rb
|
48
|
+
- lib/merb-cache/cache-store/dummy.rb
|
49
|
+
- lib/merb-cache/cache-store/file.rb
|
50
|
+
- lib/merb-cache/cache-store/memcache.rb
|
51
|
+
- lib/merb-cache/cache-store/memory.rb
|
52
|
+
- lib/merb-cache/merb-cache.rb
|
53
|
+
- lib/merb-cache/merbtasks.rb
|
54
|
+
- lib/merb-cache.rb
|
55
|
+
has_rdoc: true
|
56
|
+
homepage: http://www.merbivore.com
|
57
|
+
post_install_message:
|
58
|
+
rdoc_options: []
|
59
|
+
|
60
|
+
require_paths:
|
61
|
+
- lib
|
62
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
63
|
+
requirements:
|
64
|
+
- - ">="
|
65
|
+
- !ruby/object:Gem::Version
|
66
|
+
version: "0"
|
67
|
+
version:
|
68
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
69
|
+
requirements:
|
70
|
+
- - ">="
|
71
|
+
- !ruby/object:Gem::Version
|
72
|
+
version: "0"
|
73
|
+
version:
|
74
|
+
requirements: []
|
75
|
+
|
76
|
+
rubyforge_project:
|
77
|
+
rubygems_version: 1.0.1
|
78
|
+
signing_key:
|
79
|
+
specification_version: 2
|
80
|
+
summary: Merb plugin that provides caching (page, action, fragment, object)
|
81
|
+
test_files: []
|
82
|
+
|