-
Notifications
You must be signed in to change notification settings - Fork 116
/
abstract_strategy_store.rb
123 lines (107 loc) · 4.02 KB
/
abstract_strategy_store.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
# -*- coding: utf-8 -*-
module Merb::Cache
# A strategy store wraps one or
# more fundamental stores, acting as a middle man between caching
# requests.
#
# For example, if you need to save memory on your Memcache server,
# you could wrap your MemcachedStore with a GzipStore. This would
# automatically compress the cached data when put into the cache, and
# decompress it on the way out. You can even wrap strategy caches
# with other strategy caches. If your key was comprised of sensitive
# information, like a SSN, you might want to encrypt the key before
# storage. Wrapping your GzipStore in a SHA1Store would take
# care of that for you.
#
# The AbstractStore class defines 9 methods as the API:
#
# writable?(key, parameters = {}, conditions = {})
# exists?(key, parameters = {})
# read(key, parameters = {})
# write(key, data = nil, parameters = {}, conditions = {})
# write_all(key, data = nil, parameters = {}, conditions = {})
# fetch(key, parameters = {}, conditions = {}, &blk)
# delete(key, parameters = {})
# delete_all
# delete_all!
#
# AbstractStrategyStore implements all of these with the exception
# of delete_all. If a strategy store can guarantee that calling
# delete_all on it’s wrapped store(s) will only delete entries
# populated by the strategy store, it may define the safe
# version of delete_all. However, this is usually not the
# case, hence delete_all is not part of the
# public API for AbstractStrategyStore.
class AbstractStrategyStore < AbstractStore
# START: interface for creating strategy stores. This should/might change.
def self.contextualize(*stores)
Class.new(self) do
cattr_accessor :contextualized_stores
self.contextualized_stores = stores
end
end
class << self
alias_method :[], :contextualize
end
attr_accessor :stores
def initialize(config = {})
@stores = contextualized_stores.map do |cs|
case cs
when Symbol
Merb::Cache[cs]
when Class
cs.new(config)
end
end
end
# END: interface for creating strategy stores.
attr_accessor :stores
# determines if the store is able to persist data identified by the key & parameters
# with the given conditions.
def writable?(key, parameters = {}, conditions = {})
raise NotImplementedError
end
# gets the data from the store identified by the key & parameters.
# return nil if the entry does not exist.
def read(key, parameters = {})
raise NotImplementedError
end
# persists the data so that it can be retrieved by the key & parameters.
# returns nil if it is unable to persist the data.
# returns true if successful.
def write(key, data = nil, parameters = {}, conditions = {})
raise NotImplementedError
end
# persists the data to all context stores.
# returns nil if none of the stores were able to persist the data.
# returns true if at least one write was successful.
def write_all(key, data = nil, parameters = {}, conditions = {})
raise NotImplementedError
end
# tries to read the data from the store. If that fails, it calls
# the block parameter and persists the result.
def fetch(key, parameters = {}, conditions = {}, &blk)
raise NotImplementedError
end
# returns true/false/nil based on if data identified by the key & parameters
# is persisted in the store.
def exists?(key, parameters = {})
raise NotImplementedError
end
# deletes the entry for the key & parameter from the store.
def delete(key, parameters = {})
raise NotImplementedError
end
# deletes all entries for the key & parameters for the store.
# considered dangerous because strategy stores which call delete_all!
# on their context stores could delete other store's entrees.
def delete_all!
raise NotImplementedError
end
def clone
twin = super
twin.stores = self.stores.map {|s| s.clone}
twin
end
end
end