merb-cache 0.9.2
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 +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
|
+
|