benschwarz-merb-cache 1.0.0
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 +224 -0
- data/Rakefile +17 -0
- data/lib/merb-cache.rb +15 -0
- data/lib/merb-cache/cache.rb +91 -0
- data/lib/merb-cache/cache_request.rb +48 -0
- data/lib/merb-cache/core_ext/enumerable.rb +9 -0
- data/lib/merb-cache/core_ext/hash.rb +21 -0
- data/lib/merb-cache/merb_ext/controller/class_methods.rb +244 -0
- data/lib/merb-cache/merb_ext/controller/instance_methods.rb +163 -0
- data/lib/merb-cache/stores/fundamental/abstract_store.rb +101 -0
- data/lib/merb-cache/stores/fundamental/file_store.rb +113 -0
- data/lib/merb-cache/stores/fundamental/memcached_store.rb +110 -0
- data/lib/merb-cache/stores/strategy/abstract_strategy_store.rb +119 -0
- data/lib/merb-cache/stores/strategy/action_store.rb +61 -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/mintcache_store.rb +75 -0
- data/lib/merb-cache/stores/strategy/page_store.rb +68 -0
- data/lib/merb-cache/stores/strategy/sha1_store.rb +62 -0
- data/spec/merb-cache/cache_request_spec.rb +78 -0
- data/spec/merb-cache/cache_spec.rb +88 -0
- data/spec/merb-cache/core_ext/enumerable_spec.rb +26 -0
- data/spec/merb-cache/core_ext/hash_spec.rb +51 -0
- data/spec/merb-cache/merb_ext/controller_spec.rb +5 -0
- data/spec/merb-cache/stores/fundamental/abstract_store_spec.rb +118 -0
- data/spec/merb-cache/stores/fundamental/file_store_spec.rb +205 -0
- data/spec/merb-cache/stores/fundamental/memcached_store_spec.rb +258 -0
- data/spec/merb-cache/stores/strategy/abstract_strategy_store_spec.rb +78 -0
- data/spec/merb-cache/stores/strategy/action_store_spec.rb +208 -0
- data/spec/merb-cache/stores/strategy/adhoc_store_spec.rb +227 -0
- data/spec/merb-cache/stores/strategy/gzip_store_spec.rb +68 -0
- data/spec/merb-cache/stores/strategy/mintcache_store_spec.rb +59 -0
- data/spec/merb-cache/stores/strategy/page_store_spec.rb +146 -0
- data/spec/merb-cache/stores/strategy/sha1_store_spec.rb +84 -0
- data/spec/spec_helper.rb +95 -0
- metadata +112 -0
@@ -0,0 +1,244 @@
|
|
1
|
+
module Merb::Cache::Controller
|
2
|
+
module ClassMethods
|
3
|
+
def self.extended(base)
|
4
|
+
base.send :class_inheritable_accessor, :_cache
|
5
|
+
base._cache = {}
|
6
|
+
end
|
7
|
+
|
8
|
+
|
9
|
+
def cache!(conditions = {})
|
10
|
+
before(:_cache_before, conditions.only(:if, :unless).merge(:with => conditions))
|
11
|
+
after(:_cache_after, conditions.only(:if, :unless).merge(:with => conditions))
|
12
|
+
end
|
13
|
+
|
14
|
+
# cache is an alias to cache_action, it will take multiple :actions and pass the conditions hash for each action
|
15
|
+
#
|
16
|
+
# @param *actions<Array[Symbol]> actions to cache
|
17
|
+
#
|
18
|
+
# @param options<Hash> Conditions passed to the store and two options specific to cache
|
19
|
+
#
|
20
|
+
# @note
|
21
|
+
# Specific options for cache:
|
22
|
+
# - :store (or :stores) use the specified store
|
23
|
+
# - :params list of params to pass to the store (see _parameters_and_conditions)
|
24
|
+
#
|
25
|
+
# @example cache :index, :show, :expire_in => 30 # caches the index and show action for 30 seconds
|
26
|
+
# @example cache :index, :store => :page_store # caches the index action using the page store
|
27
|
+
# @example cache :index, :params => [:page, :q], :store => :action_store # caches the index action using the action store and passing the :page and :q params to the action store (NB. :params => <Array> has no effect on the page store)
|
28
|
+
#
|
29
|
+
# @api public
|
30
|
+
def cache(*actions)
|
31
|
+
options = extract_options_from_args!(actions) || {}
|
32
|
+
actions.each {|a| cache_action(a, options)}
|
33
|
+
end
|
34
|
+
|
35
|
+
# cache action will cache the action
|
36
|
+
# Parameters are the same as cache but only one action is allowed
|
37
|
+
#
|
38
|
+
# @api private
|
39
|
+
def cache_action(action, conditions = {})
|
40
|
+
self._cache[action] = conditions
|
41
|
+
before("_cache_#{action}_before", conditions.only(:if, :unless).merge(:with => [conditions], :only => action))
|
42
|
+
after("_cache_#{action}_after", conditions.only(:if, :unless).merge(:with => [conditions], :only => action))
|
43
|
+
alias_method "_cache_#{action}_before", :_cache_before
|
44
|
+
alias_method "_cache_#{action}_after", :_cache_after
|
45
|
+
end
|
46
|
+
|
47
|
+
# Checks if the action called with a certain request would be cached or not. Usefull for troubleshooting problems
|
48
|
+
#
|
49
|
+
# @param action<String> action to check
|
50
|
+
#
|
51
|
+
# @param request_hash<Hash> The params that the request would have. :uri and :method are also supported to indicate the :uri and :method of the request. :store and :stores indicate the cache store to use.
|
52
|
+
#
|
53
|
+
# @note
|
54
|
+
# if not specified, the default http method is :get and the default uri is '/'
|
55
|
+
#
|
56
|
+
# @return <TrueClass, FalseClass>
|
57
|
+
# True if such a request would be cached
|
58
|
+
#
|
59
|
+
# @example Project.caches? :index, :uri => '/projects', :params => {:q => 'test'}, :method => :get
|
60
|
+
# @example Project.caches? :show, :uri => url(:project, @project), :params => {:id => @project.id}
|
61
|
+
#
|
62
|
+
# @api public
|
63
|
+
def caches?(action, params = {})
|
64
|
+
controller, conditions = _controller_and_conditions(action, params)
|
65
|
+
Merb::Cache[controller._lookup_store(conditions)].writable?(controller, *controller._parameters_and_conditions(conditions))
|
66
|
+
end
|
67
|
+
|
68
|
+
# Checks if the action called with a certain request has been cached or not.
|
69
|
+
#
|
70
|
+
# @param action<String> action to check
|
71
|
+
#
|
72
|
+
# @param request_hash<Hash> The params that the request would have. :uri and :method are also supported to indicate the :uri and :method of the request. :store and :stores indicate the cache store to use.
|
73
|
+
#
|
74
|
+
# @note
|
75
|
+
# if not specified, the default http method is :get and the default uri is '/'
|
76
|
+
#
|
77
|
+
# @return <TrueClass, FalseClass>
|
78
|
+
# True if such a request has been cached
|
79
|
+
#
|
80
|
+
# @example Project.caches? :index, :uri => '/projects', :params => {:q => 'test'}, :method => :get
|
81
|
+
#
|
82
|
+
# @api public
|
83
|
+
def cached?(action, params = {})
|
84
|
+
controller, conditions = _controller_and_conditions(action, params)
|
85
|
+
Merb::Cache[controller._lookup_store(conditions)].exists?(controller, *controller._parameters_and_conditions(conditions))
|
86
|
+
end
|
87
|
+
|
88
|
+
# Returns the cache for the action with the given request
|
89
|
+
#
|
90
|
+
# @param action<String> action to check
|
91
|
+
#
|
92
|
+
# @param request_hash<Hash> The params that the request would have. :uri and :method are also supported to indicate the :uri and :method of the request. :store and :stores indicate the cache store to use.
|
93
|
+
#
|
94
|
+
# @note
|
95
|
+
# if not specified, the default http method is :get and the default uri is '/'
|
96
|
+
#
|
97
|
+
# @return <Object>
|
98
|
+
# The content of the cache if available, else nil
|
99
|
+
#
|
100
|
+
# @example Project.cache_for :index, :uri => '/projects', :params => {:q => 'test'}, :method => :get
|
101
|
+
#
|
102
|
+
# @api public
|
103
|
+
def cache_for(action, params = {})
|
104
|
+
controller, conditions = _controller_and_conditions(action, params)
|
105
|
+
Merb::Cache[controller._lookup_store(conditions)].read(controller, *controller._parameters_and_conditions(conditions).first)
|
106
|
+
end
|
107
|
+
|
108
|
+
# Deletes the cache for the action with the given request
|
109
|
+
#
|
110
|
+
# @param action<String> action
|
111
|
+
#
|
112
|
+
# @param request_hash<Hash> The params that the request would have. :uri and :method are also supported to indicate the :uri and :method of the request. :store and :stores indicate the cache store to use.
|
113
|
+
#
|
114
|
+
# @note
|
115
|
+
# if not specified, the default http method is :get and the default uri is '/'
|
116
|
+
#
|
117
|
+
#
|
118
|
+
# @example Project.delete_cache_for :index, :uri => '/projects', :params => {:q => 'test'}, :method => :get
|
119
|
+
#
|
120
|
+
# @api public
|
121
|
+
def delete_cache_for(action, params = {})
|
122
|
+
controller, conditions = _controller_and_conditions(action, params)
|
123
|
+
Merb::Cache[controller._lookup_store(conditions)].delete(controller, *controller._parameters_and_conditions(conditions).first)
|
124
|
+
end
|
125
|
+
|
126
|
+
# Caches specified with eager_cache will be run after #trigger_action has been run
|
127
|
+
# without holding some poor user up generating the cache (through run_later)
|
128
|
+
#
|
129
|
+
# @param trigger_action<Symbol, Array[*Symbol]> The actions that will trigger the eager caching
|
130
|
+
# @param target<Array[Controller,Symbol], Symbol> the target option to cache (if no controller is given, the current controller is used)
|
131
|
+
# @param opts<Hash> Request options. See note for details.
|
132
|
+
# @param blk<Block> Block run to generate the request or controller used for eager caching after trigger_action has run
|
133
|
+
#
|
134
|
+
# @note
|
135
|
+
# Valid request options are:
|
136
|
+
# - :uri the uri of the resource you want to eager cache (needed by the page store but can be provided instead by a block)
|
137
|
+
# - :method http method used (defaults to :get)
|
138
|
+
#
|
139
|
+
# @example eager_cache :update, :index, :uri => '/articles' # When the update action is completed, a get request to :index with '/articles' uri will be cached (if you use the page store, this will be stored in '/articles.html')
|
140
|
+
# @example eager_cache :create, :index # Same after the create action but since no uri is given, the current uri is used with the default http method (:get). Useful default for resource controllers
|
141
|
+
# @example eager_cache(:create, [Timeline, :index]) {{ :uri => build_url(:timelines)}}
|
142
|
+
#
|
143
|
+
# @api public
|
144
|
+
def eager_cache(trigger_actions, target = nil, opts = {}, &blk)
|
145
|
+
trigger_actions = [*trigger_actions]
|
146
|
+
target, conditions = nil, target if target.is_a? Hash
|
147
|
+
|
148
|
+
trigger_actions.each do |trigger_action|
|
149
|
+
|
150
|
+
if target.is_a? Array
|
151
|
+
target_controller, target_action = *target
|
152
|
+
else
|
153
|
+
target_controller, target_action = self, (target || trigger_action)
|
154
|
+
end
|
155
|
+
|
156
|
+
after("_eager_cache_#{trigger_action}_to_#{target_controller.name.snake_case}__#{target_action}_after", opts.only(:if, :unless).merge(:with => [target_controller, target_action, opts, blk], :only => trigger_action))
|
157
|
+
alias_method "_eager_cache_#{trigger_action}_to_#{target_controller.name.snake_case}__#{target_action}_after", :_eager_cache_after
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
# Dispatches eager caches to a worker process
|
162
|
+
#
|
163
|
+
# @param action<String> The actiont to dispatch
|
164
|
+
# @param params<Hash> params of the request (passed to the block)
|
165
|
+
# @param env<Hash> environment variables of the request (passed to the block)
|
166
|
+
# @param blk<Block> block used to build the request (should return a hash, request or a controller)
|
167
|
+
#
|
168
|
+
# @api private
|
169
|
+
def eager_dispatch(action, params = {}, env = {}, blk = nil)
|
170
|
+
kontroller = if blk.nil?
|
171
|
+
new(build_request(env))
|
172
|
+
else
|
173
|
+
result = case blk.arity
|
174
|
+
when 0 then blk[]
|
175
|
+
when 1 then blk[params]
|
176
|
+
else blk[*[params, env]]
|
177
|
+
end
|
178
|
+
|
179
|
+
case result
|
180
|
+
when NilClass then new(build_request(env))
|
181
|
+
when Hash, Mash then new(build_request(result))
|
182
|
+
when Merb::Request then new(result)
|
183
|
+
when Merb::Controller then result
|
184
|
+
else raise ArgumentError, "Block to eager_cache must return nil, the env Hash, a Request object, or a Controller object"
|
185
|
+
end
|
186
|
+
end
|
187
|
+
|
188
|
+
kontroller.force_cache!
|
189
|
+
|
190
|
+
kontroller._dispatch(action)
|
191
|
+
|
192
|
+
kontroller
|
193
|
+
end
|
194
|
+
|
195
|
+
# Builds a request that will be sent to the merb worker process to be
|
196
|
+
# cached without holding some poor user up generating the cache (through run_later)
|
197
|
+
#
|
198
|
+
# @param request_hash<Hash> hash used to describe the request
|
199
|
+
#
|
200
|
+
# @note Acceptable options for the request hash
|
201
|
+
# - :uri The uri of the request
|
202
|
+
# - :method The http method (defaults to :get)
|
203
|
+
# - :params The params
|
204
|
+
# - any env variable you may need
|
205
|
+
#
|
206
|
+
# @return <Request>
|
207
|
+
# A request for the given arguments
|
208
|
+
#
|
209
|
+
# @example build_request(:params => {:id => @article.id}, :method => :put, :uri => build_url(:article, @article)}) # a request corresponding to the update action of a resourceful controller
|
210
|
+
#
|
211
|
+
# @api public
|
212
|
+
def build_request(request_hash = {})
|
213
|
+
Merb::Cache::CacheRequest.new(request_hash.delete(:uri), request_hash.delete(:params), request_hash)
|
214
|
+
end
|
215
|
+
|
216
|
+
# @see Router.url
|
217
|
+
def build_url(*args)
|
218
|
+
Merb::Router.url(*args)
|
219
|
+
end
|
220
|
+
|
221
|
+
# Used by cache?, cached?, cache_for and delete_cache_for to generate the controller from the given parameters.
|
222
|
+
#
|
223
|
+
# @param action<String> the cached action
|
224
|
+
# @param request_hash<Hash> params from the request.
|
225
|
+
#
|
226
|
+
# @note
|
227
|
+
# in the request hash, :params, :uri and :method are supported. Additionally :store and :stores specify which store to use.
|
228
|
+
#
|
229
|
+
# @return <Array[Controller, Hash]>
|
230
|
+
# the controller built using the request corresponding to params
|
231
|
+
# the conditions for the cached action
|
232
|
+
#
|
233
|
+
# @api private
|
234
|
+
def _controller_and_conditions(action, request_hash)
|
235
|
+
conditions = self._cache[action]
|
236
|
+
conditions.merge!(request_hash.only(:store, :stores))
|
237
|
+
request_hash.extract!(:store, :stores)
|
238
|
+
controller = new(build_request(request_hash))
|
239
|
+
controller.action_name = action
|
240
|
+
|
241
|
+
[controller, conditions]
|
242
|
+
end
|
243
|
+
end
|
244
|
+
end
|
@@ -0,0 +1,163 @@
|
|
1
|
+
module Merb::Cache::Controller
|
2
|
+
module InstanceMethods
|
3
|
+
# Partial / fragment caches are written / retrieved using fetch_partial
|
4
|
+
#
|
5
|
+
# @params template<String, Symbol> The path to the template, relative to the current controller or the template root
|
6
|
+
# @params opts<Hash> Options for the partial (@see Merb::RenderMixin#partial)
|
7
|
+
# @params conditions<Hash> conditions for the store (also accept :store for specifying the store)
|
8
|
+
#
|
9
|
+
# @note
|
10
|
+
# The opts hash supports :params_for_cache which can be used to specify which parameters will be passed to the store.
|
11
|
+
# If you call `fetch_partial` with parameters that are instance of model it will fail, so you need to use :params_for_cache in this case
|
12
|
+
#
|
13
|
+
# @example fetch_partial :bar
|
14
|
+
# @example fetch_partial :foo, :with => @foo, :params_for_cache => {:foo => @foo.id}
|
15
|
+
# @example fetch_partial :store, :with => @items, :params_for_cache => {:store_version => @store.version, :store_id => @store.id}
|
16
|
+
def fetch_partial(template, opts={}, conditions = {})
|
17
|
+
template_id = template.to_s
|
18
|
+
if template_id =~ %r{^/}
|
19
|
+
template_path = File.dirname(template_id) / "_#{File.basename(template_id)}"
|
20
|
+
else
|
21
|
+
kontroller = (m = template_id.match(/.*(?=\/)/)) ? m[0] : controller_name
|
22
|
+
template_id = "_#{File.basename(template_id)}"
|
23
|
+
end
|
24
|
+
|
25
|
+
unused, template_key = _template_for(template_id, opts.delete(:format) || content_type, kontroller, template_path)
|
26
|
+
template_key.gsub!(File.expand_path(Merb.root),'')
|
27
|
+
|
28
|
+
fetch_proc = lambda { partial(template, opts) }
|
29
|
+
params_for_cache = opts.delete(:params_for_cache) || opts.dup
|
30
|
+
|
31
|
+
concat(Merb::Cache[_lookup_store(conditions)].fetch(template_key, params_for_cache, conditions, &fetch_proc), fetch_proc.binding)
|
32
|
+
end
|
33
|
+
|
34
|
+
|
35
|
+
|
36
|
+
# Used to cache the result of a long running block
|
37
|
+
#
|
38
|
+
# @params opts<Hash> options (only uses :cache_key to define the key used)
|
39
|
+
# @params conditions<Hash> conditions passed to the store (also accept :store for specifying the store)
|
40
|
+
# @params &proc<Block> block generating the result to cache
|
41
|
+
#
|
42
|
+
# @example fetch_fragment { #stuff to do}
|
43
|
+
#
|
44
|
+
# @api public
|
45
|
+
def fetch_fragment(opts = {}, conditions = {}, &proc)
|
46
|
+
if opts[:cache_key].blank?
|
47
|
+
file, line = proc.to_s.scan(%r{^#<Proc:0x\w+@(.+):(\d+)>$}).first
|
48
|
+
fragment_key = "#{file}[#{line}]"
|
49
|
+
else
|
50
|
+
fragment_key = opts.delete(:cache_key)
|
51
|
+
end
|
52
|
+
|
53
|
+
concat(Merb::Cache[_lookup_store(conditions)].fetch(fragment_key, opts, conditions) { capture(&proc) }, proc.binding)
|
54
|
+
end
|
55
|
+
|
56
|
+
def _cache_before(conditions = {})
|
57
|
+
unless @_force_cache
|
58
|
+
if @_skip_cache.nil? && data = Merb::Cache[_lookup_store(conditions)].read(self, _parameters_and_conditions(conditions).first)
|
59
|
+
throw(:halt, data)
|
60
|
+
@_cached = true
|
61
|
+
else
|
62
|
+
@_cached = false
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def _cache_after(conditions = {})
|
68
|
+
if @_cached == false
|
69
|
+
if Merb::Cache[_lookup_store(conditions)].write(self, nil, *_parameters_and_conditions(conditions))
|
70
|
+
@_cache_write = true
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
def _eager_cache_after(klass, action, options = {}, blk = nil)
|
76
|
+
unless @skip_cache
|
77
|
+
run_later do
|
78
|
+
env = request.env.dup
|
79
|
+
env.merge!(options.only(:method, :uri))
|
80
|
+
|
81
|
+
controller = klass.eager_dispatch(action, request.params.dup, env, blk)
|
82
|
+
conditions = self.class._cache[action]
|
83
|
+
|
84
|
+
Merb::Cache[controller._lookup_store(conditions)].write(controller, nil, *controller._parameters_and_conditions(conditions))
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
# After the request has finished, cache the action without holding some poor user up generating the cache (through run_later)
|
90
|
+
#
|
91
|
+
# @param action<Array[Controller,Symbol], Symbol> the target option to cache (if no controller is given, the current controller is used)
|
92
|
+
# @param options<Hash> Request options. See note for details
|
93
|
+
# @param env<Hash> request environment variables
|
94
|
+
# @param blk<Block> Block run to generate the request or controller used for eager caching after trigger_action has run
|
95
|
+
#
|
96
|
+
# @note
|
97
|
+
# There are a number of options specific to eager_cache in the conditions hash
|
98
|
+
# - :uri the uri of the resource you want to eager cache (needed by the page store but can be provided instead by a block)
|
99
|
+
# - :method http method used (defaults to :get)
|
100
|
+
# - :params hash of params to use when sending the request to cache
|
101
|
+
#
|
102
|
+
# @example eager_cache :index, :uri => '/articles' # When the update action is completed, a get request to :index with '/articles' uri will be cached (if you use the page store, this will be stored in '/articles.html')
|
103
|
+
# @example eager_cache :index # Same after the create action but since no uri is given, the current uri is used with the default http method (:get). Useful default for resource controllers
|
104
|
+
# @example eager_cache([Timeline, :index]) :uri => url(:timelines)}}
|
105
|
+
#
|
106
|
+
# @api public
|
107
|
+
def eager_cache(action, options = {}, env = request.env.dup, &blk)
|
108
|
+
unless @_skip_cache
|
109
|
+
if action.is_a?(Array)
|
110
|
+
klass, action = *action
|
111
|
+
else
|
112
|
+
klass = self.class
|
113
|
+
end
|
114
|
+
|
115
|
+
run_later do
|
116
|
+
env = request.env.dup
|
117
|
+
env.merge!(options.only(:method, :uri, :params))
|
118
|
+
controller = klass.eager_dispatch(action, {}, env, blk)
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
def skip_cache!; @_skip_cache = true; end
|
124
|
+
def force_cache!; @_force_cache = true; end
|
125
|
+
|
126
|
+
def _lookup_store(conditions = {})
|
127
|
+
conditions[:store] || conditions[:stores] || default_cache_store
|
128
|
+
end
|
129
|
+
|
130
|
+
# Overwrite this in your controller to change the default store for a given controller
|
131
|
+
def default_cache_store
|
132
|
+
Merb::Cache.default_store_name
|
133
|
+
end
|
134
|
+
|
135
|
+
#ugly, please make me purdy'er
|
136
|
+
def _parameters_and_conditions(conditions)
|
137
|
+
parameters = {}
|
138
|
+
|
139
|
+
if self.class.respond_to? :action_argument_list
|
140
|
+
arguments, defaults = self.class.action_argument_list[action_name]
|
141
|
+
arguments.inject(parameters) do |parameters, arg|
|
142
|
+
if defaults.include?(arg.first)
|
143
|
+
parameters[arg.first] = self.params[arg.first] || arg.last
|
144
|
+
else
|
145
|
+
parameters[arg.first] = self.params[arg.first]
|
146
|
+
end
|
147
|
+
parameters
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
case conditions[:params]
|
152
|
+
when Symbol
|
153
|
+
parameters[conditions[:params]] = self.params[conditions[:params]]
|
154
|
+
when Array
|
155
|
+
conditions[:params].each do |param|
|
156
|
+
parameters[param] = self.params[param]
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
return parameters, conditions.except(:params, :store, :stores, :method, :uri)
|
161
|
+
end
|
162
|
+
end
|
163
|
+
end
|
@@ -0,0 +1,101 @@
|
|
1
|
+
class Merb::Cache::AbstractStore
|
2
|
+
|
3
|
+
def initialize(config = {}); end
|
4
|
+
|
5
|
+
# determines if the store is able to persist data identified by the key & parameters
|
6
|
+
# with the given conditions.
|
7
|
+
#
|
8
|
+
# @param [#to_s] key the key used to identify an entry
|
9
|
+
# @param [Hash] parameters optional parameters used to identify an entry
|
10
|
+
# @param [Hash] conditions optional conditions that place constraints or detail instructions for storing an entry
|
11
|
+
# @return [TrueClass] the ability of the store to write an entry based on the key, parameters, and conditions
|
12
|
+
# @raise [NotImplementedError] API method has not been implemented
|
13
|
+
def writable?(key, parameters = {}, conditions = {})
|
14
|
+
raise NotImplementedError
|
15
|
+
end
|
16
|
+
|
17
|
+
# gets the data from the store identified by the key & parameters.
|
18
|
+
# return nil if the entry does not exist.
|
19
|
+
#
|
20
|
+
# @param [#to_s] key the key used to identify an entry
|
21
|
+
# @param [Hash] parameters optional parameters used to identify an entry
|
22
|
+
# @return [Object, NilClass] the match entry, or nil if no entry exists matching the key and parameters
|
23
|
+
# @raise [NotImplementedError] API method has not been implemented
|
24
|
+
def read(key, parameters = {})
|
25
|
+
raise NotImplementedError
|
26
|
+
end
|
27
|
+
|
28
|
+
# persists the data so that it can be retrieved by the key & parameters.
|
29
|
+
# returns nil if it is unable to persist the data.
|
30
|
+
# returns true if successful.
|
31
|
+
#
|
32
|
+
# @param [#to_s] key the key used to identify an entry
|
33
|
+
# @param data the object to persist as an entry
|
34
|
+
# @param [Hash] parameters optional parameters used to identify an entry
|
35
|
+
# @param [Hash] conditions optional conditions that place constraints or detail instructions for storing an entry
|
36
|
+
# @return [TrueClass, NilClass] true if the entry was successfully written, otherwise nil
|
37
|
+
# @raise [NotImplementedError] API method has not been implemented
|
38
|
+
def write(key, data = nil, parameters = {}, conditions = {})
|
39
|
+
raise NotImplementedError
|
40
|
+
end
|
41
|
+
|
42
|
+
# @param [#to_s] key the key used to identify an entry
|
43
|
+
# @param data the object to persist as an entry
|
44
|
+
# @param [Hash] parameters optional parameters used to identify an entry
|
45
|
+
# @param [Hash] conditions optional conditions that place constraints or detail instructions for storing an entry
|
46
|
+
# @return [TrueClass, NilClass] true if the entry was successfully written, otherwise nil
|
47
|
+
# @raise [NotImplementedError] API method has not been implemented
|
48
|
+
def write_all(key, data = nil, parameters = {}, conditions = {})
|
49
|
+
write(key, data, parameters, conditions)
|
50
|
+
end
|
51
|
+
|
52
|
+
# tries to read the data from the store. If that fails, it calls
|
53
|
+
# the block parameter and persists the result.
|
54
|
+
#
|
55
|
+
# @param [#to_s] key the key used to identify an entry
|
56
|
+
# @param [Hash] parameters optional parameters used to identify an entry
|
57
|
+
# @param [Hash] conditions optional conditions that place constraints or detail instructions for storing an entry
|
58
|
+
# @return [Object, NilClass] the match entry or the result of the block call, or nil if the entry is not successfully written
|
59
|
+
# @raise [NotImplementedError] API method has not been implemented
|
60
|
+
def fetch(key, parameters = {}, conditions = {}, &blk)
|
61
|
+
raise NotImplementedError
|
62
|
+
end
|
63
|
+
|
64
|
+
# returns true/false based on if data identified by the key & parameters
|
65
|
+
# is persisted in the store.
|
66
|
+
#
|
67
|
+
# @param [#to_s] key the key used to identify an entry
|
68
|
+
# @param [Hash] parameters optional parameters used to identify an entry
|
69
|
+
# @return [TrueClass] true if the key and parameters match an entry in the store, false otherwise
|
70
|
+
# @raise [NotImplementedError] API method has not been implemented
|
71
|
+
def exists?(key, parameters = {})
|
72
|
+
raise NotImplementedError
|
73
|
+
end
|
74
|
+
|
75
|
+
# deletes the entry for the key & parameter from the store.
|
76
|
+
#
|
77
|
+
# @param [#to_s] key the key used to identify an entry
|
78
|
+
# @param [Hash] parameters optional parameters used to identify an entry
|
79
|
+
# @raise [TrueClass] true if the an entry matching the key and parameters is successfully deleted, false otherwise
|
80
|
+
# @raise [NotImplementedError] API method has not been implemented
|
81
|
+
def delete(key, parameters = {})
|
82
|
+
raise NotImplementedError
|
83
|
+
end
|
84
|
+
|
85
|
+
# deletes all entries for the key & parameters for the store.
|
86
|
+
#
|
87
|
+
# @return [TrueClass] true if all entries in the store are erased, false otherwise
|
88
|
+
# @raise [NotImplementedError] API method has not been implemented
|
89
|
+
def delete_all
|
90
|
+
raise NotImplementedError
|
91
|
+
end
|
92
|
+
|
93
|
+
# dangerous version of delete_all. Used by strategy stores, which may delete entries not associated with the strategy
|
94
|
+
# store making the call.
|
95
|
+
#
|
96
|
+
# @return [TrueClass] true if all entries in the store are erased, false otherwise
|
97
|
+
# @raise [NotImplementedError] API method has not been implemented
|
98
|
+
def delete_all!
|
99
|
+
delete_all
|
100
|
+
end
|
101
|
+
end
|